使用Task的WhenAll()或WaitAll()方法时,有没有办法知道单个Task的状态。
当我为每个完成的任务使用await Task.WhenAll(tasks.ToArray())时,我想知道任务已经完成。
答案 0 :(得分:0)
有一种更好的方法可以做到这一点,但是这里有一个原始类,它接受一系列未启动的任务,并在每次执行某些任务时触发一个事件:
public class TaskBatchRunner
{
private Task[] _tasks;
public event EventHandler<Task> TaskCompleted;
public TaskBatchRunner(Task[] tasks)
{
_tasks = tasks.Select(t =>
new Task(() =>
{
t.ContinueWith(OnTaskCompleted);
t.Start();
})).ToArray();
}
public void Run()
{
foreach (var t in _tasks) t.Start();
Task.WaitAll(_tasks);
}
private void OnTaskCompleted(Task completedTask)
{
TaskCompleted?.Invoke(this, completedTask);
}
}
用法:
var taskRunner = new TaskBatchRunner(tasks.ToArray());
taskRunner.TaskCompleted += MyTaskCompleted;
taskRunner.Run();
...
private void MyTaskCompleted(object sender, Task e)
{
System.Diagnostics.Debug.WriteLine($"task {e.Id} completed!");
}
答案 1 :(得分:0)
要报告async
或并发进程的进度,请使用IProgress<T>
抽象。使用Progress<T>
implmentation,您可以轻松捕获当前上下文,并在后台工作时在ui上下文中运行进度更新/完成表达式:
public class WorkItem {
public async Task DoWork(IProgress<bool> completionNotification) {
await Task.Delay(TimeSpan.FromSeconds(2));
//Work Done
completionNotification.Report(true);
}
//Get, Set, Fire Property change etc
public bool Completed {
get; set;
}
}
public class ViewModel {
public async void ButtonClickHandler(object sender, EventArgs e) {
var workitemTasks = WorkItems.Select(workItem =>
workItem.DoWork(new Progress<bool>(done => workItem.Completed = done)))
.ToList();
await Task.WhenAll(workitemTasks);
}
//Get, Set, Fire Property change etc
public IEnumerable<WorkItem> WorkItems {
get; set;
}
}
<强> More Info 强>