[英]Awaiting events to be fired from task list
我正在使用Task.Run()
啟動幾個任務。 在每個任務中,我都為InstallCompleted
定義了一個事件處理程序。 然后,我await
這些任務完成。 棘手的是,下面看到的installModule.Install()
方法會立即返回,因為它在內部調用了OneWay
WCF服務調用。
那么,如何await
直到上述每個任務中的installModule
所有實例都觸發了各自的InstallCompleted
事件? 如果有更好的方法可以做到這一點,我全神貫注。
var installTasks = new List<Task>();
foreach (var targetMachine in vm.TargetMachines)
{
var installTask = Task.Run(() =>
{
foreach (var module in Modules)
{
var installModule = module as IInstallModule; // copy closure variable
if (installModule == null)
continue;
installModule.InstallCompleted += (s, e) =>
{
//TODO set some flag indicating this install is complete
};
var ip = new Progress<InstallProgress>();
installModule.Install(targetMachine.MachineName, ip);
}
});
installTasks.Add(installTask);
}
await Task.WhenAll(installTasks); // unblocks immediately because installModule.Install() above returns immediately
每當你互操作async
與另一種異步API的 ,你可以使用TaskCompletionSource<T>
作為一個異步一個時間信號。 就個人而言,我喜歡將此作為擴展方法:
public static Task<InstallCompletedResult> InstallAsync(
this IInstallModule module, string machineName,
IProgress<InstallProgress> progress = null)
{
var tcs = new TaskCompletionSource<InstallCompletedResult>();
InstallCompletedEventHandler handler = null;
handler = (s, e) =>
{
module.InstallCompleted -= handler;
if (e.Exception != null)
tcs.TrySetException(e.Exception);
else
tcs.TrySetResult(e.Result);
};
module.InstallCompleted += handler;
module.Install(machineName, progress);
return tcs.Task;
}
一旦有了互操作性,就可以很容易地進行消費:
var installTask = Task.Run(async () =>
{
var tasks = new List<Task>();
foreach (var module in Modules)
{
var installModule = module as IInstallModule; // copy closure variable
if (installModule == null)
continue;
var ip = new Progress<InstallProgress>();
tasks.Add(installModule.InstallAsync(targetMachine.MachineName, ip));
}
});
或者,更簡單地說:
var installTask = Task.Run(async () =>
{
var tasks = Modules.OfType<IInstallModule>()
.Select(module => module.InstallAsync(targetMachine.MachineName,
new Progress<InstallProgress>()));
await Task.WhenAll(tasks);
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.