监控任务完成

Onu*_*nur -2 c# task

我运行几个任务并将它们保存在列表中以检查它们是否已经完成.

我发现来自async方法RanToCompletion的任务总是显示为任务本身仍在运行.

Task在两种情况下,有没有办法从对象获取"完整"信息?

这是一个显示此行为的简单测试用例.我运行两个任务,有/没有async方法,并在完成期间和完成后检查状态.

private void test()
{

    ;
    Action actionAsync = funcAsync;
    Task taskAsync = Task.Run(actionAsync);
    Action action = func;
    Task task = Task.Run(action);

    var statusAsync = taskAsync.Status;
    var status = task.Status;

    // stati are either WaitingToRun or Running

    Thread.Sleep(TimeSpan.FromSeconds(2));

    // Now it's quite certain, that both have started

    var statusAsync2 = taskAsync.Status;
    var status2 = task.Status;

    Debug.Assert(statusAsync2 == TaskStatus.RanToCompletion);
    Debug.Assert(status2 == TaskStatus.Running);

    ;

    Thread.Sleep(TimeSpan.FromSeconds(12));

    // Now it's quite certain, that both have finished

    var statusAsync3 = taskAsync.Status;
    var status3 = task.Status;
    ;

    Debug.Assert(statusAsync3 == TaskStatus.RanToCompletion);
    Debug.Assert(status3 == TaskStatus.RanToCompletion);

}



private async void funcAsync()
{
    await Task.Delay(TimeSpan.FromSeconds(10));
}
private  void func()
{
    Thread.Sleep(TimeSpan.FromSeconds(10));
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 8

我发现来自异步方法的任务总是显示为RanToCompletion,尽管任务本身仍在运行.

是的,因为你的void方法已经完成了,这就是所有Task.Run的调用.如果你使用:

private async Task FuncAsync()
{
    await Task.Delay(TimeSpan.FromSeconds(10));
}
Run Code Online (Sandbox Code Playgroud)

并使用Func<Task>,而不是Action,那么你会打电话Task.Run(Func<Task>)和一切都会好的.

简短而完整的例子:

using System;
using System.Threading;
using System.Threading.Tasks;

class Test
{
    static void Main()
    {
        Func<Task> func = FuncAsync;
        Task task = Task.Run(func);
        for (int i = 0; i < 7; i++)
        {
            Console.WriteLine(task.Status);
            Thread.Sleep(1000);
        }        
    }

    private static async Task FuncAsync()
    {
        await Task.Delay(TimeSpan.FromSeconds(5));
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

WaitingForActivation
WaitingForActivation
WaitingForActivation
WaitingForActivation
WaitingForActivation
RanToCompletion
RanToCompletion
Run Code Online (Sandbox Code Playgroud)

尽可能避免编写void异步方法.它们基本上只应用于事件处理程序.