当特定任务没有结果时,不要等待其他任务完成

时间:2017-07-31 11:51:43

标签: c# entity-framework async-await

假设我有2个任务(A和B)。我可以完全并行运行它们,所以我可以使用:

await Task.WhenAll(A,B)
var resA = await A;
var resB = await B;

现在我想不等待B,如果A(基于某些条件)返回false。 B的结果不再让我感兴趣了。可以这样做吗?

In addition to this answers below:

因此,确保在创建任务时立即启动任务。所以下面的代码应该可以工作。

var A = Usermanager.FindAsync(email.ToString(), password.ToString());
var B = db.Table.AnyAsync(r=> r.email == email.Tostring()); //simplified action
var user = await A;
if (user != null)
{
    var resB = await B;
}
else
{
    // A was false, so don't await B
}

如果B生成一个长时间运行的sql语句。仍然使用取消令牌导致以下代码释放SQL Server资源会更好吗?

var cts = new CancellationTokenSource();
var A = Usermanager.FindAsync(email.ToString(), password.ToString());
var B = db.Table.AnyAsync(r=> r.email == email.Tostring(), cts.Token); //simplified long running sql action
var user = await A;
if (user != null)
{
    var resB = await B;
}
else
{
    // A was false, cancel query from B
    cts.Cancel();
}

2 个答案:

答案 0 :(得分:3)

  

现在我想不等待B,如果A(基于某些条件)返回false。 B的结果不再让我感兴趣了。可以这样做吗?

当然,不要await它:

if (await A)
{
  var resB = await B;
}
else
{
  // A was false, so don't await B
}

答案 1 :(得分:-2)

删除的答案正在链接到How to cancel and raise an exception on Task.WhenAll if any exception is raised?。但是猜测代码后的分钟并不是正确的方法:

var cts = new CancellationTokenSource();
var A = Usermanager.FindAsync(email.ToString(), password.ToString());
var B = db.Table.AnyAsync(r=> r.email == email.Tostring(), cts.Token) //simplified action
var C = A.ContinueWith(t => { if (t.Result == null) { cts.Cancel(); } }, TaskContinuationOptions.OnlyOnRanToCompletion);
await Task.WhenAll(C,B);

当然你可以改变ContinuationOption,但是为了使用任务的结果,我相信它应该是OnlyRanToCompletion。上面应该取消B,因此当A的结果为null(无结果)时,完成Task.WhenAll命令。