c# - 嵌套Task.WhenAll有什么限制吗?

标签 c# .net async-await parallel-processing

让我们想象一些抽象代码

    private void Main()
    {
        var workTask1 = DoWork1();
        var workTask2 = DoWork2();
        var workTask3 = DoWork3();

        await Task.WhenAll(workTask1, workTask2, workTask3);

        AnalyzeWork(workTask1.Result, workTask2.Result, workTask3.Result);
    }

    private async Task<object> DoWork1()
    {
        var someOperationTask1 = someOperation1();
        var someOperationTask2 = someOperation2();

        await Task.WhenAll(someOperationTask1, someOperationTask2);

        return new object
        {
            SomeOperationResult1 = someOperationTask1.Result,
            SomeOperationResult2 = someOperationTask2.Result,
        };
    }

    private async Task<object> DoWork2()
    {
        var someOperationTask3 = someOperation3();
        var someOperationTask4 = someOperation4();

        await Task.WhenAll(someOperationTask3, someOperationTask4);

        return new object
        {
            SomeOperationResult3 = someOperationTask3.Result,
            SomeOperationResult4 = someOperationTask4.Result,
        };
    }

    private async Task<object> DoWork3()
    {
        var someOperationTask5 = someOperation5();
        var someOperationTask6 = someOperation6();

        await Task.WhenAll(someOperationTask5, someOperationTask6);

        return new object
        {
            SomeOperationResult5 = someOperationTask5.Result,
            SomeOperationResult6 = someOperationTask6.Result,
        };
    }

其中 3 个方法并行运行,每个方法都包含 2 个并行操作。并将 3 个方法的结果传递给某个方法。

我的问题是有什么限制吗?可以嵌套 Task.WhenAll 吗?嵌套 Task.WhenAll 和一级 Task.WhenAll 操作有什么区别?

最佳答案

唯一的限制是系统的可用内存。 Task.WhenAll 方法为每个未完成的任务附加一个延续,并在该任务完成时分离该延续。 continuation 是类似于 Task 的轻量级对象。它与调用 Task.ContinueWith 时得到的结果非常相似方法。每个延续的权重或多或少约为 100 个字节。它不太可能对您的程序产生任何显着影响,除非您需要同时Task.WhenAll 数千万个(或更多)任务。

如果你想直观地了解这个方法的内部结构,下面是其实现的粗略草图:

// For demonstration purposes only. This code is full of bugs.
static Task WhenAll(params Task[] tasks)
{
    var tcs = new TaskCompletionSource();
    int completedCount = 0;
    foreach (var task in tasks)
    {
        task.ContinueWith(t =>
        {
            completedCount++;
            if (completedCount == tasks.Length) tcs.SetResult();
        });
    }
    return tcs.Task;
}

关于c# - 嵌套Task.WhenAll有什么限制吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72026350/

相关文章:

c# - 无法在 web api Controller 中命中断点

c# - Facebook 应用程序中不允许使用 HTTP 动词 POST 来访问路径 '/'

c# - 创建Word文档时如何更改表格的列宽

c# - 使用现有的哈希集作为键来创建新字典

javascript - 为什么 'await' 不等待 axios 请求完成?

javascript - react .js : Will multiple async setState method calls always re-render after and impact performance?

c# - 以编程方式运行 CREATE PROCEDURE 脚本

c# - 缓慢嵌套 'for' 循环读取 Excel 对象

c# - 用于降低 Visual Studio C# 中的接口(interface)编程摩擦的工具?

c# - 使用任务并行库Task.WhenAny()时如何处理异常