首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C#中,回调执行的行为是什么(假设配置等待没有设置为false,并且假设存在同步上下文)?

在C#中,回调执行的行为是什么(假设配置等待没有设置为false,并且假设存在同步上下文)?
EN

Stack Overflow用户
提问于 2021-09-02 08:38:00
回答 1查看 57关注 0票数 1

在Javascript中,回调(等待的异步函数)只在调用堆栈为空时运行。如果有多个回调,那么它们就会排队(在事件循环队列中),在下一个回调更改运行之前,只会运行一个回调。

在C#的情况下(假设ConfigureAwait没有设置为false,也就是说,callabck将在同一个线程中运行;也假设存在同步上下文winforms):

  1. 是否立即运行回调,而不等待调用堆栈为空?

  1. 假设有多个回调排队,那么当一个回调正在运行,另一个回调准备执行时,那么当新的回调想要运行时,运行的回调是否挂起?或者是连续的?
EN

回答 1

Stack Overflow用户

发布于 2021-09-04 13:24:21

答案是,它取决于当前的SynchronizationContext,如果是null,则取决于当前的TaskScheduler

awaited Task完成时,您已经将Awaitable配置为捕获上下文并在其上恢复,几乎可以肯定的是,该延续不能立即继续(线程可能正在忙着执行其他事情)。所能做的就是安排在当前SynchronizationContext上稍后执行的延续,这是通过调用SynchronizationContext.Post()来完成的。

如何实现此Post方法取决于SynchronizationContext (即abstract)。如果使用WPF,则SynchronizationContextDispatcherSynchronizationContext。在那里,Post是通过调用Dispatcher.BeginInvoke()DispatcherPriority.Normal来实现的。

换句话说,您的继续将在dispatcher上排队等待稍后的执行,并具有正常的优先级。其他委托可能具有更高的优先级(例如,DispatcherPriority.Input),但最终您的委托将在dispatcher上执行。

有两件事要注意:

  1. BeginInvoke只是对您的委托进行排队。它不会马上执行。换句话说,排队您的委托是非常快的。
  2. 上面的解释应该说明为什么异步等待只是语法糖。您可以自己完成所有这些调用,但是编译器会为您完成这些任务,从而使您的代码流更加自然。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69026848

复制
相关文章

相似问题

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