首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >同步上下文

同步上下文
EN

Stack Overflow用户
提问于 2019-03-04 16:24:29
回答 1查看 596关注 0票数 0

我理解.ConfigureAwait(false)意味着continuation不一定要在进入时所在的同一线程上。

所以我想知道在someUIButton_click中我会得到什么样的同步上下文。

static async void someUIButton_click()
{
   await T1();
   // Am I sur to be on the UI thread ?
}

static async Task T1() => await doSomethingAsync().ConfigureAwait(false)

上下文: C#、winforms、.Net 4.7

EN

回答 1

Stack Overflow用户

发布于 2019-03-04 16:29:04

SynchronizationContext和执行上下文

每个线程都有一个与之关联的上下文,这也称为当前上下文,这些上下文可以在线程之间共享。ExecutionContext包含程序在其中执行的当前环境或上下文的相关元数据。

SynchronizationContext表示一个抽象,它定义了执行应用程序代码的位置。SynchronizationContext是代码运行的当前环境的表示,它提供了一种将工作单元排队到上下文的方法。SynchronizationContext有一个与之相关的上下文,在不同的情况下,不同的框架可能代表不同的东西。例如

默认DispatcherSynchronizationContext

  • The Winform应用程序- WindowsFormsSynchronizationContext

  • WPF APS AspNetSynchronizationContext

  • SynchronizationContext - default (ThreadPool) SynchronizationContext
  • ASP.Net

await如何使用SynchronisationContext的

Async/await只是一个编译器魔术,它使编写异步东西变得更容易(它不会让你的代码异步运行),当它看到一个await时,它所做的就是将你的方法拆分到一个状态机中,当你等待的东西完成执行时,状态机被恢复,你的代码继续运行。恢复执行称为延续。

await关键字的一个特性是,它在运行异步操作之前捕获当前的SynchronizationContext,然后它将继续发送到该SynchronizationContext,这意味着如果您在卸载时正在UI线程上,一旦它完成运行,您的代码将继续在UI线程上执行(这称为await )。

ConfigureAwait()

所有ConfigureAwait(false)所做的就是配置任务,这样await之后的context就不必在调用者上下文中运行了。这可能有几个好处,其中之一是小的性能增益,更有争议的是在某些情况下阻止死锁。

答案

每次调用await时,它都会创建一个状态机来实现异步等待模式的奇迹,并设置一个延续。

仅仅因为您将ConfigureAwait设置为false嵌套在另一个await (状态机)中并不会改变原始调用,该调用被设置为在调用同步上下文(如果适用)上继续执行。

旁注: someUIButton_click在运行时未被观察到,您应该进行适当的错误检查

更新

,这意味着我可以在T1中做任何我想做的事情,只要它不与某些UI组件交互

但是,您“看似”可以自由地从someUIButton_clickT1访问UI组件,例外情况是,在T1中的 await之后,您已经配置了任务,以便configured不需要返回到调用上下文。在这里访问UI组件可能会给您带来问题。

那么在someUIButton_click中的await之后会怎样呢

在这种情况下,任务(默认情况下)捕获了当前上下文(假设是您的UI线程),并且将在该上下文上继续执行。每个嵌套的等待都是一种不同的情况,调用await (状态机)可以选择它继续运行的上下文

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54979220

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档