任务状态更改为RanToCompletion如果任务计谋的东西 [英] Task status changes to RanToCompletion if the Task await's something

查看:1718
本文介绍了任务状态更改为RanToCompletion如果任务计谋的东西的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题描述在这里发现了同样的问题 - <一个href="http://social.msdn.microsoft.com/Forums/en-US/edee635c-9534-4a71-8be3-c5ab17d80cff/task-status-changes-to-rantocompletion-after-using-await?forum=winappswithcsharp"相对=nofollow> MSDN开发人员论坛。问题没有一个公认的答案,既不任何给定的答案可以应用到我的情况下(因此一个不同的问题)。

The question describes the same problem found here - MSDN Developer Forum. The question does not have an accepted answer, neither any of the answers given can be applied to my case (hence a different question).

问题也衍生出一个I asked pviously $ P $,但由于不同性质和更具体的问题,我要问一个新的。

Question is also derived from one I asked previously, but, due to different nature and more specific problem, I'm asking a new one.

全部code可以在这里找到: http://pastebin.com/uhBGWC5e
*唯一改变的是任务完成检查(,而 - > Task.WhenAll )。

Full code can be found here: http://pastebin.com/uhBGWC5e
* Only thing changed is the task completion check (while -> Task.WhenAll).

在等待一个任务,任务状态更改为 RanToCompletion 即使里面一个异步操作,该任务仍在运行。

When awaiting an async operation inside of a Task, the Task status changes to RanToCompletion even though, the Task is still running.

现在,让我们来看看设置:

Now, let's see the setup:

// Start async.
Task t1 = Task.Factory.StartNew(Accept, s1);
Task t2 = Task.Factory.StartNew(Accept, s1);

Task.WhenAll(t1, t2).Wait();

接受方法:

public static async void Accept(object state)
{
    TcpListenerEx server = (TcpListenerEx) state;

    IPEndPoint endPoint = server.LocalEndpoint as IPEndPoint;

    Log("Accepting clients on {0}", endPoint);

    while (true)
    {
        var client = server.AcceptTcpClientAsync();

        if (client == null)
        {
            Log("Null error on accept");
            break;
        }

        TcpClient connected = (TcpClient) client;
        servers[server].Add(connected);

        bool stop = await Task<Task<bool>>.Factory.StartNew(Listen, connected).Unwrap();

        if (stop == true)
        {
            break;
        }
    }

    // Stop the server.
    server.Stop();

    Log("Stoppped {0}", endPoint);
}

由于TaskStatus变为RanToCompletion时, Task.WhenAll()等待()通话结束很快痕本身,导致程序有待进一步执行,最终 - 终止。

Because of TaskStatus changing to RanToCompletion, the Task.WhenAll().Wait() call marks itself finished fairly quickly, resulting in program to be executed further, eventually - terminated.

不过,在接受任务,在理论上,应该永远不会停止,它监听连接,直到明确停止。

But, the Accept task, in theory, should never stop, it's listening for connections until explicitly stopped.

什么是这里的问题是造成任务被标记为 RanToCompletion prematurely?

What is the problem here that's causing the Task to be marked as RanToCompletion prematurely?

推荐答案

我可以用少得多的code重现此问题:

I can reproduce this issue with far less code:

void Main()
{
    Task t1 = Task.Factory.StartNew(Accept);
    t1.Wait();
    Console.WriteLine("Main ended");
}

public static async void Accept()
{
    while (true)
    {
        await Task.Delay(1000);
    }

    Console.WriteLine("Stoppped");
}

但是,这正常工作:

But this works correctly:

void Main()
{
    Task t1 = Accept();
    t1.Wait();
    Console.WriteLine("Main ended");
}

public static async Task Accept()
{
    while (true)
    {
        await Task.Delay(1000);
    }

    Console.WriteLine("Stoppped");
}

基本上,使用 Task.Factory.StartNew(),你正在创建一个工作基于一个单独的螺纹越来越催生调用给定的委托(即接受()法)。该接受方法本身(像任何好的异步法)实际上立即返回。所以调用它立即完成其任务的线程,因此工作创建重新present线程也随即结束。

Basically, by using Task.Factory.StartNew(), you are creating a Task based on a separate thread getting spawned to invoke the given delegate (the Accept() method). The Accept method itself (like any good async method) actually returns immediately. So the thread that calls it finishes its task immediately, so the Task created to represent that thread also finishes immediately.

如果您允许接受()返回工作而不是无效,那么工作它返回的是你,如果你要等到它通过其所有的等待运行,应等待秒。

If you allow Accept() to return a Task instead of void, then the Task that it returns is what you should be awaiting if you want to wait until it has run through all its awaits.

这篇关于任务状态更改为RanToCompletion如果任务计谋的东西的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆