如您所知,Task.ConfigureAwait(false)在等待不需要捕获同步上下文的代码中的任务时调用是个好主意,否则会导致死锁.
那么,您需要多久捕获一次同步上下文?我的练习,很少.在大多数情况下,我正在使用"库"代码,这几乎迫使我一直使用Task.ConfigureAwait(false)它.
所以我的问题非常简单:为什么Task.ConfigureAwait(false)不是任务的默认选项?强制使用"高级"代码不是更好Task.ConfigureAwait(true)吗?这有历史原因,还是我错过了什么?
小智 15
大多数使用的代码.ConfigureAwait(false)也有效,尽管不是最佳的.ConfigureAwait(true).是的,不是所有代码,但仍然是最多的.当前默认设置允许最高百分比的代码工作,而无需修改典型程序员遗憾地无法理解的设置.
一个不同的默认值只会导致成千上万的问题,为什么代码不起作用,更糟糕的是,成千上万的答案形式为"微软糟透了,他们会让你写Control.CheckForIllegalCrossThreadCalls = false;在每个程序.为什么不是默认?" 而不是实际添加适当的.ConfigureAwait(true)调用.
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)且更容易检测,因此选择默认值是更为保守的选择.
仅仅因为您的典型用例需要ConfigureAwait(false),这并不意味着它是"正确"或最常用的选项.
async/await的一个目的是编写响应式GUI程序.在这种情况下,在将一些工作卸载到Task之后返回UI线程是至关重要的,因为UI更新只能从大多数Windows GUI平台上的主线程发生.Async/await帮助GUI开发人员做正确的事情.
这不是默认选项更有意义的唯一示例.我只能推测,但我怀疑对ConfigureAwait默认的决定是基于确保异步对尽可能少的摩擦起作用,对于Microsoft预期它将被最多使用的用例.不是每个人都写框架.
| 归档时间: |
|
| 查看次数: |
11570 次 |
| 最近记录: |