监控任务完成
Monitoring Task completion
我 运行 几个任务并将它们保存在一个列表中以检查它们是否已经完成。
我发现来自 async
方法的任务总是显示为 RanToCompletion
,尽管任务本身仍然是 运行ning。
有没有办法在这两种情况下从 Task
对象获取 "is complete" 信息?
这是一个显示此行为的简单测试用例。我 运行 两个任务,with/without 一个 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));
}
I discovered that tasks that come from an async method are always shown as RanToCompletion although the task itself was still running.
是的,因为您的 void
方法已经完成,这就是 Task.Run
调用的全部内容。如果您改为使用:
private async Task FuncAsync()
{
await Task.Delay(TimeSpan.FromSeconds(10));
}
并使用 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));
}
}
输出:
WaitingForActivation
WaitingForActivation
WaitingForActivation
WaitingForActivation
WaitingForActivation
RanToCompletion
RanToCompletion
尽可能避免编写 void
异步方法。它们基本上应该只用于事件处理程序。
我 运行 几个任务并将它们保存在一个列表中以检查它们是否已经完成。
我发现来自 async
方法的任务总是显示为 RanToCompletion
,尽管任务本身仍然是 运行ning。
有没有办法在这两种情况下从 Task
对象获取 "is complete" 信息?
这是一个显示此行为的简单测试用例。我 运行 两个任务,with/without 一个 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));
}
I discovered that tasks that come from an async method are always shown as RanToCompletion although the task itself was still running.
是的,因为您的 void
方法已经完成,这就是 Task.Run
调用的全部内容。如果您改为使用:
private async Task FuncAsync()
{
await Task.Delay(TimeSpan.FromSeconds(10));
}
并使用 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));
}
}
输出:
WaitingForActivation
WaitingForActivation
WaitingForActivation
WaitingForActivation
WaitingForActivation
RanToCompletion
RanToCompletion
尽可能避免编写 void
异步方法。它们基本上应该只用于事件处理程序。