【问题标题】:Don't wait for other task to finish when a specific task has no result当特定任务没有结果时,不要等待其他任务完成
【发布时间】:2017-08-02 16:32:20
【问题描述】:

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

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

现在,如果 A(基于某些条件)返回 false,我不想等待 B。 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();
}

【问题讨论】:

    标签: c# entity-framework async-await


    【解决方案1】:

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

    当然,只是不要await它:

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

    【讨论】:

    • 这样两个动作都是同步执行的(从彼此的角度来看)我想同时启动A和B(异步)但忽略B
    • @Dexter 然后在等待A 之前启动B,只是不要await B.
    • @Dexter:在这段代码中,A 和B 都是任务,它们都已经在进行中。它们不是同步执行的,也不是串行执行的。
    • 您能再解释一下吗?我根据您的回答编辑了问题并进行了跟进。它不适合评论。
    • @Dexter:是的,TAP tasks are returned "hot" - 也就是说,已经在进行中。是的,如果 B 长时间运行并消耗资源并且可以取消,那么最好根据您的代码取消它。
    【解决方案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 命令。

    【讨论】:

      猜你喜欢
      • 2013-05-26
      • 1970-01-01
      • 1970-01-01
      • 2015-11-16
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多