异步总是WaitingForActivati​​onWaitingForActivati、on

2023-09-03 07:02:24 作者:因为太想念

我试图弄清异步&放大器; 计谋关键字是一回事,但输出的是不是我期待的。

I am trying to figure out what the async & await keywords are all about, however the output isn't what I'm expecting.

控制台应用程序如下:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Foo called");
        var result = Foo(5);

        while (result.Status != TaskStatus.RanToCompletion)
        {
            Console.WriteLine("Thread ID: {0}, Status: {1}", Thread.CurrentThread.ManagedThreadId, result.Status);
            Task.Delay(100).Wait();
        }

        Console.WriteLine("Result: {0}", result.Result);
        Console.WriteLine("Finished.");
        Console.ReadKey(true);
    }

    private static async Task<string> Foo(int seconds)
    {
        return await Task.Run(() =>
            {
                for (int i = 0; i < seconds; i++)
                {
                    Console.WriteLine("Thread ID: {0}, second {1}.", Thread.CurrentThread.ManagedThreadId, i);
                    Task.Delay(TimeSpan.FromSeconds(1)).Wait();
                }

                return "Foo Completed.";
            });
    }
}

的输出是:

Foo called
Thread ID: 10, Status: WaitingForActivation
Thread ID: 6, second 0.
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 6, second 1.
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 6, second 2.
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 6, second 3.
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 6, second 4.
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Thread ID: 10, Status: WaitingForActivation
Result: Foo Completed.
Finished..

我期待看到的状态,一旦该方法开始从 WaitingForActivati​​on 改变。

如何才能保持这种状态和积极?

How can it stay in this state and be active?

推荐答案

有关我的回答,这是值得记住的是第三方物流(Task-Parallel-Library), 工作类和 TaskStatus 枚举之前异步等待关键字和异步等待的关键字进行了介绍是不是原来的动机的第三方物流。

For my answer, it is worth remembering that the TPL (Task-Parallel-Library), Task class and TaskStatus enumeration were introduced prior to the async-await keywords and the async-await keywords were not the original motivation of the TPL.

在标记为异步方法的背景下产生的工作不是任务重presenting的方法的执行,但工作的方法的延续。

In the context of methods marked as async, the resulting Task is not a Task representing the execution of the method, but a Task for the continuation of the method.

这是仅能够使用几个可能的状态:

This is only able to make use of a few possible states:

取消 在断陷 RanToCompletion WaitingForActivati​​on

据我所知,运行可能似乎已经不是 WaitingForActivati​​on 更好的默认,但是这可能会产生误导,因为大部分的时间,异步方法是的执行的是不实际运行(即可能是伺机 -ing别的东西)。另一种选择可能是一个新值添加到 TaskStatus ,然而,这可能是一个重大更改现有的应用程序和库。

I understand that Runningcould appear to have been a better default than WaitingForActivation, however this could be misleading, as the majority of the time, an async method being executed is not actually running (i.e. it may be await-ing something else). The other option may have been to add a new value to TaskStatus, however this could have been a breaking change for existing applications and libraries.

所有这些都是非常不同的利用 Task.Run 的是原太平人寿的一部分时,这是能够利用所有可能的值在 TaskStatus 枚举。

All of this is very different to when making use of Task.Run which is a part of the original TPL, this is able to make use of all the possible values of the TaskStatus enumeration.

如果您希望保留的异步方法的状态轨迹,看看在IProgress(T)接口,这将允许您报告正在取得的进展。该博客文章,Async 4.5:在异步API的将提供关于使用 IProgress(T)接口的进一步信息,使进度和取消

If you wish to keep track of the status of an async method, take a look at the IProgress(T) interface, this will allow you to report the ongoing progress. This blog post, Async in 4.5: Enabling Progress and Cancellation in Async APIs will provide further information on the use of the IProgress(T) interface.