【问题标题】:StaTaskScheduler and await continuationStaTaskScheduler 并等待继续
【发布时间】:2013-11-05 12:41:07
【问题描述】:

我正在使用 Stephen Toub 的 StaTaskScheduler,原因描述为 here

据我了解,任务调度是Task Scheduler的职责,而awaitcontinuation是Synchronization Context的职责(如有错误请指正)。

现在我想在由StaTaskScheduler 创建的STA 线程之一上运行的任务代码中使用await。我是否应该安装自定义同步上下文,以确保代码在await 之后的相同 STA 线程上继续执行?

【问题讨论】:

    标签: c# .net multithreading task-parallel-library async-await


    【解决方案1】:

    我在intro to async blog post 中介绍了await 的行为。

    默认情况下,await 会捕获当前的SynchronizationContext除非是null,在这种情况下它将捕获当前的TaskScheduler

    所以,答案是否定的,您不需要安装自定义SynchronizationContext。在StaTaskScheduler 执行的任务中使用时,await 将默认捕获该任务调度程序并继续执行该StaTaskScheduler 执行的另一个任务。

    请注意,StaTaskScheduler 确实维护了一个集合 STA 线程,并且可以在任何这些线程上执行延续。如果这是不可接受的,您需要将StaTaskScheduler 限制为单个线程(通过将1 传递给其构造函数)。

    【讨论】:

    • 再次感谢斯蒂芬的全面回答,您的博客是必读的。我还有一个问题。我仍然想保留一个 STA 线程池,但我希望每个任务代码都有线程亲和性,当它的 STA 线程已分配时,直到工作完成。如果没有自定义SynchronizationContext,这仍然可以完成吗?
    • 这在SynchronizationContext 级别无法解决。当您安装SynchronizationContext 时,您实际上是在说您控制了该线程的核心循环。但在这种情况下,您不需要;核心循环在StaTaskScheduler 中,它不尊重线程亲和性。在您的情况下,AFAIK 最干净的解决方案是编写您自己的类型,该类型维护一个 StaTaskSchedulers 池,每个池包含一个线程。
    • @avo:再想一想,一个更简单的解决方案可能是使用my AsyncContext队列到StaTaskScheduler的(更高级别的)任务。 AsyncContext.Run 将安装线程仿射 SynchronizationContext 并等待所有 async 方法完成后再返回。这可能不是您想要的(STA 线程将被阻塞直到每个操作完成),但它比维护StaTaskSchedulers 池更容易。
    • 顺便说一句,AsyncContext.Run 可以安装 SynchronizationContext,因为它确实提供了自己的(临时)核心循环。
    • 听起来很有趣,我会考虑借用你的AsyncContext,谢谢@StephenCleary。
    猜你喜欢
    • 2014-05-28
    • 2020-05-07
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-14
    • 2020-08-23
    相关资源
    最近更新 更多