当所有 + 继续,最后

本文关键字:最后 继续 | 更新日期: 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 块。 无法保证StopStepsTrace.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); }
    }