C# 等待多个可选任务

C# 等待多个可选任务,c#,.net,asynchronous,task,C#,.net,Asynchronous,Task,您好,我想知道是否有更干净的方法来编写下面的异步代码。基本上我想等待所有任务,但其中一个任务是可选的。这感觉不必要的复杂,我想如果我可以通过一些回调来完成,但还没有弄明白 var mobile = true; var task1 = _service.Async1(); var tasks = new List<Task> { task1 }; Task<int> task2 = null; if (!mobile) { task2 = _servic

您好,我想知道是否有更干净的方法来编写下面的异步代码。基本上我想等待所有任务,但其中一个任务是可选的。这感觉不必要的复杂,我想如果我可以通过一些回调来完成,但还没有弄明白

var mobile = true;

var task1 = _service.Async1();
var tasks = new List<Task>
{
    task1
};

Task<int> task2 = null;
if (!mobile)
{
    task2 = _service.Async2();
    tasks.Add(task2);
}

await Task.WhenAll(tasks);

var result1 = task1.Result;

if (!mobile)
{
    result2 = task2.Result;
    // Do stuff
}
var mobile=true;
var task1=_service.Async1();
var tasks=新列表
{
任务1
};
task2=null;
如果(!移动)
{
task2=_service.Async2();
任务。添加(任务2);
}
等待任务。何时(任务);
var result1=task1.Result;
如果(!移动)
{
结果2=任务2.结果;
//做事
}

无需创建列表并立即等待所有结果。为什么不在需要时等待它呢?如果
task2
的运行时间比
task1
长得多,您至少可以在
task2
完成之前就开始处理它

大概是这样的:

var task1 = _service.Async1();

Task<int> task2 = null;
if (!mobile)
{
    task2 = _service.Async2();
}

var result1 = await task1;

if (!mobile)
{
    var result2 = await task2;
    // Do stuff
}
var task1=\u service.Async1();
task2=null;
如果(!移动)
{
task2=_service.Async2();
}
var result1=等待任务1;
如果(!移动)
{
var result2=等待任务2;
//做事
}

无需创建列表并立即等待所有结果。为什么不在需要时等待它呢?如果
task2
的运行时间比
task1
长得多,您至少可以在
task2
完成之前就开始处理它

大概是这样的:

var task1 = _service.Async1();

Task<int> task2 = null;
if (!mobile)
{
    task2 = _service.Async2();
}

var result1 = await task1;

if (!mobile)
{
    var result2 = await task2;
    // Do stuff
}
var task1=\u service.Async1();
task2=null;
如果(!移动)
{
task2=_service.Async2();
}
var result1=等待任务1;
如果(!移动)
{
var result2=等待任务2;
//做事
}


您是否需要
result1
来处理
result2
(我们在这里看到“
//Do stuff
”)?e、 g.“
stuff
”是否使用了
result1
?您可以在移动案例中替换虚拟的预完成任务
var results=Task.WaitAll(_service.Async1(),mobile?Task.FromResult(0):_service.Async2())
现在,
results[0]
的结果是
Async1()
如果调用,
results[1]
的结果是
Async2()
;否则它是零。@spender不是在这种情况下,不是。@RaymondChen是的,我也尝试过类似的方法,但我真的不太喜欢这种方法。您是否需要
result1
来处理
result2
(我们看到“
//Do stuff
”)?e、 g.“
stuff
”是否使用了
result1
?您可以在移动案例中替换虚拟的预完成任务
var results=Task.WaitAll(_service.Async1(),mobile?Task.FromResult(0):_service.Async2())
现在,
results[0]
的结果是
Async1()
如果调用,
results[1]
的结果是
Async2()
;否则它是零。@spender不是在这种情况下,不是。@RaymondChen是的,我也尝试过类似的方法,但我真的不太喜欢这种方法。我刚刚意识到,你的代码有一个行为改变。如果
task2
出现异常并且
mobile
true
则OP的代码将从
任务引发异常。当所有
出现时,您的代码将使异常不被注意。这样做没有什么错,只是OP应该意识到的行为变化。它还允许您在
task2
仍在运行时保留代码块的作用域。如果
\u service.Async3()
稍后出现,并且启动时不需要运行其他操作,这也可能导致问题。再说一遍,没什么问题,只是要注意副作用。@JonHanna为什么?我没有看到task1在启动task2的呼叫之前被等待。@JonHanna什么?不,
await
不是这样工作的<代码>等待
不会启动任务,异步方法本身就是这样做的。不,我只是误读了事情的顺序。忽略我之前的评论。啊,是的,当然,谢谢!我很想用惠纳尔。我仍然会在实际的代码中使用它,但我会将可选任务分解出来,并让它自己等待。如果
task2
出现异常并且
mobile
true
则OP的代码将从
任务引发异常。当所有
出现时,您的代码将使异常不被注意。这样做没有什么错,只是OP应该意识到的行为变化。它还允许您在
task2
仍在运行时保留代码块的作用域。如果
\u service.Async3()
稍后出现,并且启动时不需要运行其他操作,这也可能导致问题。再说一遍,没什么问题,只是要注意副作用。@JonHanna为什么?我没有看到task1在启动task2的呼叫之前被等待。@JonHanna什么?不,
await
不是这样工作的<代码>等待
不会启动任务,异步方法本身就是这样做的。不,我只是误读了事情的顺序。忽略我之前的评论。啊,是的,当然,谢谢!我很想用惠纳尔。我仍然会在实际的代码中使用它,但会中断可选任务,并让它自己等待。