通过 Continuewith 捕获多个任务回调

Catch multiple Task callbacks via Continuewith

我想 运行 同时执行多个任务。每个任务都会 return 一个值类型。

谁能告诉我如何通过 ContinueWith 捕获所有回调?

我的测试代码:

        static async Task<List<string>> ListAsync()
        {
            await Task.Delay(1000);
            return new List<string>() { "Item 1", "Item 2" };
        }

        static async Task<int> IntAsync()
        {
            await Task.Delay(1000);
            return 10;
        }

        static async Task<string> StringAsync()
        {
            await Task.Delay(1000);
            return "My string";
        }

        static async Task Test()
        {
            Task t1 = StringAsync();
            Task t2 = IntAsync();
            Task t3 = ListAsync();
            await Task.WhenAny(t1, t2, t3).ContinueWith(t =>
            {
                //how can I catch callbacks here?
            });
        }

如果不想调用不同continuation的任务,需要为每个task指定continuation:

static async Task Test()
{
    Task t1 = StringAsync().ContinueWith(t => System.Console.Out.WriteLine("string"));
    Task t2 = IntAsync().ContinueWith(t => System.Console.Out.WriteLine("int"));
    Task t3 = ListAsync().ContinueWith(t => System.Console.Out.WriteLine("list"));
    await Task.WhenAny(t1, t2, t3); 
    // use WhenAll if you want to wait until all tasks are done
}

WhenAny 将在任何子任务完成时完成,然后触发延续,因此延续只会被调用一次。

如果想在所有任务完成后调用一次回调,最简单的方法是这样:

static async Task Test()
{
    Task t1 = StringAsync();
    Task t2 = IntAsync();
    Task t3 = ListAsync();
    await Task.WhenAll(t1, t2, t3); 
    // your continuation logic here
}

如果您尝试检索所有任务的结果,一旦它们全部完成,您可以简单地使用 Task.WhenAll。如果所有任务 return 结果相同,则 Task.WhenAll(Task[] 重载将 return 一个任务。在这种情况下,await Task.WhenAll 将 return 一个包含任务结果的数组,顺序为:

var t1=Task.Run(()=>{...;return 1});
var t2=Task.Run(()=>{...;return 2});
var t3=Task.Run(()=>{...;return 3});

int[] results=await Task.WhenAll(t1,t2,t3);
//Check t1's result
Debug.Assert(results[0]==1);

当任务 return 的结果不同时, Task.WhenAll(params Task[]) 被调用其中 return 只是一个任务。您仍然可以访问每个任务的结果,使用它的 Result 属性 而没有任何阻塞的风险:

var t1=Task.Run(()=>{...;return 1});
var t2=Task.Run(()=>{...;return "Hi"});
var t3=Task.Run(()=>{...;return new[]{1,2,3}});

await Task.WhenAll();

Debug.Assert(t2.Result=="Hi");

没有理由在使用 await 时使用 ContinueWith,因为等待 与使用 ContinueWith 大致相同 - 它不'开始任何异步执行,它 等待而不阻塞 已经 运行 任务完成,它提取结果并将同步上下文设置为等待开始之前的状态。