考虑:
async Task FooAsync()
{
await BarAsync().ConfigureAwait(false);
UpdateUI(); // Bug
}
我正在寻找一种系统地确保不会发生这种情况的方法。
也许是一种命名约定,其中必须在UI线程上运行的方法获得特殊后缀。或静态检查,其中方法上的[UIThreadOnlyAttribute]意味着任何调用者必须具有相同的属性,并且可能不会调用ConfigureAwait(false)
。
有什么建议吗?
答案 0 :(得分:7)
只要您的应用程序合理分层,就不应该成为问题。
UI层(例如,事件处理程序)和逻辑UI层(例如,ViewModel)需要UI上下文,不应使用ConfigureAwait
。其他图层应使用ConfigureAwait
。这是一个很适合我的简单指南。
答案 1 :(得分:2)
作为完整性检查,在UpdateUI
方法的开头,您可以手动验证当前线程是否具有正确的同步上下文。对于WinForms应用程序,它可能如下所示:
void UpdateUI()
{
Debug.Assert(SynchronizationContext.Current is WindowsFormsSynchronizationContext);
// ...
// Do the actual UI update
}
对于WPF应用,第一行是:
Debug.Assert(SynchronizationContext.Current is DispatcherSynchronizationContext);
这适合我。
答案 2 :(得分:0)
可以使用编译时代码注入(例如PostSharp)来执行此操作。我从来没有做过这样的事情,但文档似乎表明你可以提出一个创造性的解决方案。使用PostSharp链接到Custom Architecture Constraints。