【发布时间】:2019-08-13 03:36:42
【问题描述】:
我正在尝试将现有的同步应用程序重构为使用 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 参数)。
我不知道该怎么做。
【问题讨论】:
-
您是否尝试过传递一些回调或事件,然后从高层监听该事件或回调?
-
参见this answer(非常简单,与您已有的代码相似)及其副本,它使用专有实现。还有许多其他示例。
-
谢谢。我知道如何使用 IProgress,但这不是问题所在。问题是最后(即使那里有一个循环),我正在等待一个 Task.WhenAll,并且我没有指示何时完成单个保存任务。
-
然后修改
SaveToFile(filePath),以便您可以从那里更新IProgress。您在这里有一个并行的进度,您可以更新每个文件的进度+1,将进度最大值设置为您要复制的文件数。我不知道DoSomethingThatTakesSomeTime();在做什么,需要更多时间才能完成以及您要通知的进度。如果最终的文件复制操作足够了,那就去吧。
标签: c# asynchronous async-await