如果不需要访问 UI 元素,就可以配置 await,以避免使用同步上下文。下面的代码片段演示了配置,并说明为什么不应该从后台线程上访问 UI 元素。
使用 OnStartAsyncConfigureAwait 方法,在将 UI 线程的 ID 写入文本输入后,将调用本地函数 AsyncFunction。在这个本地函数中,启动线程是在调用异步方法 Task.Delay 之前写入的。使用此方法返回的任务,将调用 ConfigureAwait。在这个方法中,任务的配置是通过传递设置为 false 的 continueOnCapturedContext 参数来完成的。通过这种上下文配置,会发现等待之后的线程不再是 UI 线程。使用不同的线程将结果写入 result 变量即可。如 try 块所示c#await,千万不要从非 UI 线程中访问 UI 元素。得到的异常包含 HRESULT 值,如 when 子句所示。只有这个异常在 catch 中捕获:结果返回给调用者。对于调用方,也调用了 ConfigureAwait,但是这次,continueOnCapturedContext 设置为 true。在这里c#await,在等待之前和之后,方法都在 UI 线程中运行:
private async void OnStartAsyncConfigureAwait(object sender, RoutedEventArgs e)
{
text1.Text = $"UI thread: {GetThread()}";
string s = await AsyncFunction().ConfigureAwait(
continueOnCapturedContext: true);
// after await, with continueOnCapturedContext true we are back in the UI thread
text1.Text += $"n{s}nafter await: {GetThread()}";
async Task<string> AsyncFunction()
{
string result = $"nasync function: {GetThread()}n";
await Task.Delay(1000). ConfigureAwait(continueOnCapturedContext: false);
result += $"nasync function after await : {GetThread()}";
try
{
text1.Text = "this is a call from the wrong thread";
return "not reached";
}
catch (Exception ex) when (ex.HResult == -2147417842)
{
return result;
// we know it's the wrong thread
// don't access UI elements from the previous try block
}
}
}
运行应用程序时,可以看到如下输出。在等待后的异步本地函数中,使用了另一个线程。文本 not reached 从来没有写过,因为抛出了异常:
UI thread: thread 3
async function: thread 3
async function after await: thread 6
after await: thread 3
技术群:添加小编微信并备注进群
限时特惠:本站每日持续更新海量设计资源,一年会员只需29.9元,全站资源免费下载
站长微信:ziyuanshu688
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。