当所有 + 继续,最后
本文关键字:最后 继续 | 更新日期: 2023-09-27 17:56:02
我想同时运行三个顶级进程。完成其中两个进程后,我有需要运行的子进程,一个是需要并发运行的集合。我面临的唯一问题是刷新最终在子进程完成之前执行。我插入了一些跟踪语句,结果如下:
Pulling AssetList
Pulling MarketImports
Pulling AccountBalance
AccountBalance Pulled
MarketImports Pulled
Pulling WalletTransactions
AssetList Pulled
Pulling BlueprintList
Pulling MarketOrders
Pulling IndustryJobs
Flushing
MarketOrders Pulled
BlueprintList Pulled
IndustryJobs Pulled
WalletTransactions Pulled
如何在子进程完成后进行刷新?有问题的代码如下:
private async Task DoPull(string token, string name, Func<string, Task> func)
{
Trace.WriteLine(string.Format("Pulling {0}", name));
await func(token);
StopSteps(token, name);
Trace.WriteLine(string.Format("{0} Pulled", name));
}
try
{
await Task.WhenAll(
DoPull(tk, "AssetList", _assetMapper.Pull).ContinueWith(async c => await Task.WhenAll(
DoPull(tk, "BlueprintList", _blueprintMapper.Pull),
DoPull(tk, "MarketOrders", _orderMapper.Pull),
DoPull(tk, "IndustryJobs", _jobMapper.Pull))),
DoPull(tk, "MarketImports", _marketMapper.Pull).ContinueWith(async c =>
await DoPull(tk, "WalletTransactions", _transactionMapper.Pull)),
DoPull(tk, "AccountBalance", _balanceMapper.Pull));
}
catch (Exception)
{
StopSteps(token, _running.ToArray());
}
finally { Flush(token); }
真正的答案
在 DoPull 中,一旦等待的函数完成,执行将返回给调用方。 这意味着一旦所有其他等待在其他DoPull
调用中完成,它将继续返回 main 方法,并点击 finally 块。 无法保证StopSteps
或Trace.WriteLine
调用将在发生这种情况之前执行。
不正确的东西
ContinueWith
内部的处决在任何地方都没有等待。
您应该使用ContinueWith<Task>
来获取该功能。
这样内联所有内容有点困难,也许将其分解一下,以便更容易地挑选出步骤是什么?
private async Task Method()
{
try
{
var assetList = DoPull(tk, "AssetList", _assetMapper.Pull)
.ContinueWith<Task>(t => Task.WhenAll(
DoPull(tk, "BlueprintList", _blueprintMapper.Pull),
DoPull(tk, "MarketOrders", _orderMapper.Pull),
DoPull(tk, "IndustryJobs", _jobMapper.Pull));
var marketImport = DoPull(tk, "MarketImports", _marketMapper.Pull)
.ContinueWith<Task>(t => DoPull(tk, "WalletTransactions", _transactionMapper.Pull));
var accountBalance = DoPull(tk, "AccountBalance", _balanceMapper.Pull);
await Task.WhenAll(assetList, marketImport, accountBalance);
}
catch (Exception)
{
StopSteps(token, _running.ToArray());
}
finally { Flush(token); }
}
编辑
private async Task PullAssetList()
{
await DoPull(tk, "AssetList", _assetMapper.Pull);
await Task.WhenAll(
DoPull(tk, "BlueprintList", _blueprintMapper.Pull),
DoPull(tk, "MarketOrders", _orderMapper.Pull),
DoPull(tk, "IndustryJobs", _jobMapper.Pull));
}
private async Task PullMarketImport()
{
await DoPull(tk, "MarketImports", _marketMapper.Pull);
await DoPull(tk, "WalletTransactions", _transactionMapper.Pull);
}
private async Task PullAccountBalance()
{
await DoPull(tk, "AccountBalance", _balanceMapper.Pull);
}
private async Task Method()
{
try
{
await Task.WhenAll(PullAssetList(), PullMarketImport(), PullAccountBalance());
}
catch (Exception)
{
StopSteps(token, _running.ToArray());
}
finally { Flush(token); }
}