Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过Continuewith捕获多个任务回调_C#_.net_Task - Fatal编程技术网

C# 通过Continuewith捕获多个任务回调

C# 通过Continuewith捕获多个任务回调,c#,.net,task,C#,.net,Task,我想同时运行多个任务。每个任务都将返回一个值类型 谁能告诉我如何通过ContinueWith捕获所有回调 我的测试代码: static async Task<List<string>> ListAsync() { await Task.Delay(1000); return new List<string>() { "Item 1", "Item 2" }; }

我想同时运行多个任务。每个任务都将返回一个值类型

谁能告诉我如何通过
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?
            });
        }
静态异步任务ListAsync()
{
等待任务。延迟(1000);
返回新列表(){Item 1”,“Item 2};
}
静态异步任务IntAsync()
{
等待任务。延迟(1000);
返回10;
}
静态异步任务StringAsync()
{
等待任务。延迟(1000);
返回“我的字符串”;
}
静态异步任务测试()
{
任务t1=StringAsync();
任务t2=IntAsync();
任务t3=ListAsync();
等待任务。在任何时候(t1、t2、t3)。继续(t=>
{
//我怎么能在这里接到回电?
});
}

如果不想调用具有不同延续性的任务,则需要为每个任务指定延续性:

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.whalll
。如果所有任务返回相同的结果,则重载将返回一个任务。在这种情况下,
wait Task.whalll
将按顺序返回包含任务结果的数组:

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);
当任务返回不同的结果时,调用只返回任务的。但是,您仍然可以使用其
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");

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

为什么不使用
任务。当所有
时?你为什么要把
ContinueWith
wait
混在一起?@Luizgrs这是个非常糟糕的主意-
。结果
块。此外,完全没有理由这样做,因为任务完成后,
wait
会返回结果,这是您误解的。你为什么要使用
ContinueWith
?只要做
等待任务即可(t1、t2、t3)就完成了。@幸运的是编码问题是
继续进行
,而不是
等待
。只需调用
var results=wait Task.WhenAll(t1、t2、t3)
并检查任务的结果取决于您想对其执行的操作。如果您只是想以某种方式处理它们中的每一个,您不需要
任务;var result2=等待t2;var result3=等待t3。如果您在所有
时都使用了
,您只需在之后使用
t1.result
等读取结果即可。当然,
Task.whalll
会返回所有任务,因此如果需要对所有任务执行相同的操作,只需在结果上为每个
构建一个
foreach
。当任何
将按顺序返回任务的结果时,没有理由使用这样的代码-
,将
ContinueWith
async/await
混合在一起似乎很奇怪。对我来说,这通常是一个或另一个决定,对后者有强烈的偏见。我相信OP认为,当任何人以某种方式循环完成所有任务时,但我不想偏离原来的问题太远,对不起,但是在你的例子中,有没有另一种方法可以将3个
ContinueWith
组合成1行而不是3行呢?这就是为什么我把
wait
放在
ContinueWith
之前的原因。是的,我更喜欢这种方法而不是使用
foreach
。我能有一个小问题吗?我注意到您说的关于
ContinueWith
:`它提取结果并将同步上下文设置为等待启动
之前的状态。为什么不将结果
t1.Result
t2.Result
t3.Result
作为演示?