我正在尝试将现有的同步应用程序重构为使用Async / Await的应用程序。该WPF应用最初是使用BackgroundWorker线程编写的,该线程调用了一堆同步方法。我走到了最深的层次,然后向上工作,在其中一些似乎不是taking too long的地方使用await Task.Run(()..)将这些方法转换为异步方法。
尽管如此,我仍然坚持。我想传递一个IProgress参数,以便能够将反馈反馈到UI中-最后一种最深的方法(执行时间最长的方法)是这样写的:
public static Task<bool> SaveToFileAsync(string filePath)
{
return Task.Run(() => SaveToFile(filePath));
/*
SaveToFile calls into an unmanaged dll that uses a few loops and writes
to file using fopen/fwrite...
*/
}
private async void CreateObjectAndSaveToFile(/*IProgress progress*/)
{
List<Task> SaveFileTaskArray = new List<Task>();
int index = 0;
foreach (...)
{
//
{
DoSomethingThatTakesSomeTime();
//Start Async Task to save this SomeThing to file
SaveFileTaskArray.Add(SaveToFileAsync(fileName));
}
index++;
}
await Task.WhenAll(SaveFileTaskArray);
}
现在,如果我像这样在UI端调用CreateObjectAndSaveToFile():
await CreateObjectAndSaveToFile();
我得到了预期的效果-UI响应并且文件被一个接一个地保存(可以是10-20个文件)。但是为了完整起见,我想为此添加一个进度条(并因此一直添加IProgress参数)。
我不确定该怎么做。
答案 0 :(得分:0)
您在评论中提到已经知道如何使用IProgress
。因此,如果您希望在每个任务完成时报告进度,可以使用WhenAny()
而不是WhenAll()
,并在完成时从列表中将其删除。像这样:
while (SaveFileTaskArray.Count > 0) {
var finishedTask = await Task.WhenAny(SaveFileTaskArray);
SaveFileTaskArray.Remove(finishedTask);
//Report progress of how many are left
progress.Report(SaveFileTaskArray.Count);
}
如果您想了解更多信息,Microsoft文档实际上有整篇文章:Start Multiple Async Tasks and Process Them As They Complete