为什么ConfigureAwait(false)不是默认选项?

RX_*_*_RX 57 c# async-await

如您所知,Task.ConfigureAwait(false)在等待不需要捕获同步上下文的代码中的任务时调用是个好主意,否则会导致死锁.

那么,您需要多久捕获一次同步上下文?我的练习,很少.在大多数情况下,我正在使用"库"代码,这几乎迫使我一直使用Task.ConfigureAwait(false)它.

所以我的问题非常简单:为什么Task.ConfigureAwait(false)不是任务的默认选项?强制使用"高级"代码不是更好Task.ConfigureAwait(true)吗?这有历史原因,还是我错过了什么?

小智 15

大多数使用的代码.ConfigureAwait(false)也有效,尽管不是最佳的.ConfigureAwait(true).是的,不是所有代码,但仍然是最多的.当前默认设置允许最高百分比的代码工作,而无需修改典型程序员遗憾地无法理解的设置.

一个不同的默认值只会导致成千上万的问题,为什么代码不起作用,更糟糕的是,成千上万的答案形式为"微软糟透了,他们会让你写Control.CheckForIllegalCrossThreadCalls = false;在每个程序.为什么不是默认?" 而不是实际添加适当的.ConfigureAwait(true)调用.

  • @rianjs我的回答的重点是,许多程序员不知道自己在做什么。关键是设计选择是基于此。删除那意味着我剩下的答案不再有意义。 (2认同)

Tav*_*nes 10

查看该链接的第二个示例解决方案:

public async void Button1_Click(...)
{
  var json = await GetJsonAsync(...);
  textBox1.Text = json;
}

public class MyController : ApiController
{
  public async Task<string> Get()
  {
    var json = await GetJsonAsync(...);
    return json.ToString();
  }
}
Run Code Online (Sandbox Code Playgroud)

如果是默认行为ConfigureAwait(false),则该textBox1.Text = json;语句将在随机线程池线程而不是UI线程上执行.

两个片段看起来都像是有人可以合理写的代码,默认情况下其中一个必须被破坏.由于死锁比线程不安全的访问更危险ConfigureAwait(true)且更容易检测,因此选择默认值是更为保守的选择.

  • @Servy 非常正确,但是在选择默认值时,需要在可能的死锁和可能的线程不安全访问之间进行权衡。死锁是更好(更保守)的默认设置。 (3认同)
  • 该提案的重点是,每次您希望代码在“await”之后在 UI 线程中运行时,您都需要使用“ConfigureAwait(true)”(或某种等价物),而不是您不能这样做根本。 (2认同)
  • @Servy - 如果您使用 .ConfigureAwait(false) 调用上面的代码,那么它就是错误的,这不是偏好问题。在 UI 上下文中,您不能这样做,因为您可能不会返回到 UI 线程。因此,这是一个很好的答案,解释了为什么默认值是这样的。显然 OP 不编写 UI 代码,因此更喜欢将默认值设置为 false,但我同意 Tavian 的观点,这是更安全的默认值。 (2认同)

dri*_*iis 9

仅仅因为您的典型用例需要ConfigureAwait(false),这并不意味着它是"正确"或最常用的选项.

async/await的一个目的是编写响应式GUI程序.在这种情况下,在将一些工作卸载到Task之后返回UI线程是至关重要的,因为UI更新只能从大多数Windows GUI平台上的主线程发生.Async/await帮助GUI开发人员做正确的事情.

这不是默认选项更有意义的唯一示例.我只能推测,但我怀疑对ConfigureAwait默认的决定是基于确保异步对尽可能少的摩擦起作用,对于Microsoft预期它将被最多使用的用例.不是每个人都写框架.

  • 对不起,那是胡扯。绝大多数现代开发都不在Windows GUI或IIS应用程序服务器上。由于上世纪的这种偏见,我们需要指定在使用时强制使用ConfigureAwait(false)。顺便说一句,这是什么意思?不配置等待?这是一个asinine名称,因为只有一个选项,并且基本上没有线程关联。有人想到将配置await而不是将其称为affinity(false)或更明智的想法。 (3认同)