【问题标题】:Async Await and Task.Run issue异步等待和 Task.Run 问题
【发布时间】:2018-11-02 13:25:57
【问题描述】:

我需要知道这些记录有什么不同,如果有,它们是什么? 这对我来说相当困难:

1) Task.Run(async () => { await CheckVerification(); });
2) Task.Run(() => CheckVerification());
3) await Task.Run(async () => { await CheckVerification(); });

【问题讨论】:

  • 仅供参考:这些选项都不正确。最常见的是await CheckVerification();,在某些特殊情况下使用await Task.Run(() => CheckVerification());
  • @CamiloTerevinto。你好。如果我不想等待结果。我只需要创建任务并为用户返回 OK。这个任务会像背景一样工作吗?
  • 那么你只需要CheckVerification(),唯一正确的即发即弃选项
  • 你觉得他们每个人都做什么?你知道这些表达式中执行的每个底层操作都在做什么吗?如果没有,你不明白哪些?您是否研究过这些操作中的每一个以及它们的作用?在那项研究中,您有什么不理解或感到困惑或矛盾的地方?
  • 所有这些方法都会创建 1 个额外的、不必要的任务。仅将 Task.Run 用于 CPU 绑定工作。

标签: c# multithreading task


【解决方案1】:

如果我们暂时忘记Task.Run,也许更容易理解其中的区别。您的第 1 点和第 2 点之间的区别与等待或仅从 Task 返回方法返回内部任务基本相同:

// 1)
public async Task WithAwait() => await SomeOtherTaskReturningMethod();

// 2)
public Task WithoutAwait() => return SomeOtherTaskReturningMethod();

第一个创建另一个任务,它包装了内部的任务,这是一个很小的开销,但是这两种方法在功能上几乎相同。一个小的区别是当SomeOtherTaskReturningMethod 抛出异常时,内部任务的AggregatedException 将被解包,并且(第一个)内部异常将被进一步抛出。当然,事情仍然取决于外部任务发生了什么。在您的第三点中,它也处于等待状态,因此您将从外部任务(如果有)中获得未包装的异常,而第一个和第二个示例只是一劳永逸。

现在让我们再次考虑Task.Run。主要问题为什么这个方法有重载,接受Tasks(实际上是Task返回回调),当你也可以简单地调用await CheckVerification();并得到相同的结果? (我知道这不是问题的一部分,但可能值得澄清一下)

所以存在这种Task.Run 重载的原因是Task 返回方法本身不一定在另一个线程上执行(我建议this reading)。例如,它可以只通过网络套接字发送一条消息并返回一个Task,这将在收到特定答案时完成。这使得操作异步,仍然不是多线程的。

如果您有这样的任务,并且希望强制它在另一个线程上执行,那么您可以通过Task.Run 执行它,它使用默认调度程序并最终在池线程上执行您的任务。

值得一提的是,这是一种非常罕见的情况。在大多数情况下,您应该依赖 Task 返回方法的内部实现。

TL;DR:

所以我认为真正的问题是是否

await CheckVerification();

await Task.Run(() => CheckVerification());

是更好的解决方案(或者可能是其中之一没有await,即即发即弃模式)。在大多数情况下,我会投票给第一个,但如果您真的确信CheckVerification 返回的任务必须分配给一个池线程(无论它是否在内部执行),那么第二个选项也可以是合理的.

【讨论】:

    【解决方案2】:

    1) 开始一个任务。该任务将等待内部的方法,但是是异步的,因此您的 UI 或调用线程不会阻塞。

    2) 启动一个任务,它启动另一个任务。一切都是异步运行的,没有任何等待,完全触发并忘记。

    3) 将启动一个任务,该任务启动一个方法并等待它,返回执行上下文,让调用线程以其等待放弃执行上下文,让调用此的方法继续执行,直到它等待它方法。

    【讨论】:

    • 1 和 2 都是完全即发即弃的操作
    • 所有的表达式都是异步的,所以#1 没有描述任何事物之间的区别,它适用于所有事物。如前所述,#2 并不是#3 中列出的唯一“即发即弃”选项,此处未列出的每个选项之间也存在许多差异。
    猜你喜欢
    • 2012-11-12
    • 2019-02-19
    • 2015-09-28
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 2018-12-09
    • 2017-04-01
    相关资源
    最近更新 更多