简体   繁体   English

如何获取使用SynchronizationContext的任务? 那么SynchronizationContext是如何使用的呢?

[英]How to get a Task that uses SynchronizationContext? And how are SynchronizationContext used anyway?

I am still learning the whole Task-concept and TPL. 我还在学习整个任务概念和TPL。 From my current understanding, the SynchronizationContext functions (if present) are used by await to dispatch the Task "somewhere". 根据我目前的理解, await使用SynchronizationContext函数(如果存在)来“分配”任务。 On the other hand, the functions in the Task class do not use the context, right? 另一方面, Task类中的函数不使用上下文,对吧?

So for example Task.Run(...) will always dispatch the action on an worker thread of the thread pool and ignore the SynchronizationContext.Current completely. 因此,例如, Task.Run(...)将始终在线程池的工作线程上调度操作,并完全忽略SynchronizationContext.Current await Foobar() would use the context to execute the generated task after the await ? await Foobar()会在await之后使用上下文来执行生成的任务吗?

If that is true, my question is: How can I obtain a Task , that actually runs an action but is dispatched using SynchronizationContext.Current.Send/Post ? 如果这是真的,我的问题是:我如何获得一个实际运行动作但使用SynchronizationContext.Current.Send/Post调度的Task

And can anyone recommend a good introduction into SynchronizationContext , especially when and how they are used by the rest of the framework? 任何人都可以推荐对SynchronizationContext一个很好的介绍,特别是它们何时以及如何被框架的其余部分使用? The MSDN seems to be very quiet about the class. MSDN似乎对这堂课非常安静。 The top Google hits ( here and here ) seem to be tailored to Windows Forms dispatching only. 顶级Google点击( 此处此处 )似乎仅适用于Windows Forms调度。 Stephen Cleary wrote an article which is nice to learn what contexts already exist and how they work, but I lack understanding of where and when they are actually used. Stephen Cleary撰写了一篇文章 ,很高兴了解已经存在的背景以及它们是如何工作的,但我不了解实际使用的地点和时间。

How can I obtain a Task, that actually runs an action but is dispatched using SynchronizationContext.Current.Send/Post? 如何获取实际运行操作但使用SynchronizationContext.Current.Send / Post调度的任务?

Use special task scheduler: 使用特殊任务调度程序:

Task.Factory.StartNew(
    () => {}, // this will use current synchronization context
    CancellationToken.None, 
    TaskCreationOptions.None, 
    TaskScheduler.FromCurrentSynchronizationContext());

And can anyone recommend a good introduction into SynchronizationContext 任何人都可以推荐一个很好的SynchronizationContext介绍

Look at the article It's All About the SynchronizationContext by Stephen Cleary. 请看Stephen Cleary撰写的关于SynchronizationContext的文章。

As you're learning this, it's important to point out that Task as used by the TPL is quite different than Task as used by async/await , even though they're the same type. 当你正在学习这一点,指出这是非常重要Task 13759的TPL是相当大的差异Task 13759异步/ AWAIT,即使他们是同一类型。 For example, TPL commonly uses parent/child tasks, but async / await does not. 例如,TPL通常使用父/子任务,但async / await不使用。

TPL uses task schedulers to execute its tasks. TPL使用任务调度程序来执行其任务。 As Dennis pointed out, TaskScheduler.FromCurrentSynchronizationContext will give you a task scheduler that uses Post on the current SynchronizationContext to execute its task. 正如Dennis所指出的, TaskScheduler.FromCurrentSynchronizationContext将为您提供一个任务调度程序,它使用当前SynchronizationContext上的Post来执行其任务。

async / await usually does not use task schedulers. async / await通常不使用任务调度程序。 I have an introductory async / await post on my blog that includes context information, and I also mention it briefly in my MSDN article (it's easy to overlook, though). 我在我的博客上有一个介绍性的async / await帖子 ,其中包含上下文信息,我在MSDN文章中也简要提到过(虽然很容易忽略)。 Essentially, when an async method suspends at an await , by default it will capture the current SynchronizationContext (unless it is null , in which case it will capture the current TaskScheduler ). 本质上,当async方法在await处挂起时,默认情况下它将捕获当前的SynchronizationContext (除非它为null ,在这种情况下它将捕获当前的TaskScheduler )。 When the async method resumes, it resumes executing in that context. async方法恢复时,它将继续在该上下文中执行。

Dennis pointed out the TPL way of scheduling a task to the current SynchronizationContext , but in async / await world, that approach isn't necessary. Dennis指出了将任务安排到当前SynchronizationContext的TPL方式,但是在async / await世界中,这种方法不是必需的。 Rather, you can explicitly schedule tasks to the thread pool via Task.Run : 相反,您可以通过Task.Run显式地将任务计划到线程池:

async Task MyMethodAsync()
{
  // Whee, on a SynchronizationContext here!
  await Task.Run(() => { }); // Ooo, on the thread pool!
  // Back on the SynchronizationContext ...
  //  ... automagically!
}

I wrote my SynchronizationContext article precisely because the MSDN docs were so lacking. 我正好写了我的SynchronizationContext文章,因为MSDN文档非常缺乏。 I have a little more information on my blog , but all the important bits are in the MSDN article. 在我的博客上更多的信息 ,但所有重要的部分都在MSDN文章中。 Many types use AsyncOperation rather than SynchronizationContext directly; 许多类型直接使用AsyncOperation而不是SynchronizationContext ; the best documentation for this is buried under the EAP docs (section "Threading and Context") . 最好的文档隐藏在EAP文档(“线程和上下文”部分)下 But I should also point out that EAP is effectively obsolete due to async / await , so I wouldn't write code using AsyncOperation (or SynchronizationContext ) - unless I was actually writing my own SynchronizationContext . 但我还应该指出,由于async / await ,EAP实际上已经过时了,所以我不会使用AsyncOperation (或SynchronizationContext )编写代码 - 除非我实际编写自己的 SynchronizationContext

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何获取特定 WPF 窗口的当前 SynchronizationContext? - How do you get the current SynchronizationContext for a specific WPF window? 线程中的C#线程:如何获取SynchronizationContext.Current? - C# Thread in Thread: how to get SynchronizationContext.Current? 如何附加非UI线程的SynchronizationContext - How to attach SynchronizationContext of Non-UI thread 如何对涉及SynchronizationContext的代码进行单元测试? - How to unit test code involving SynchronizationContext? 如何在没有SynchronizationContext的情况下使用INotifyPropertyChanged来确保线程安全? - How to be thread-safe using INotifyPropertyChanged with no SynchronizationContext? 仅在任务RanToCompletion上使用SynchronizationContext - Use SynchronizationContext only on Task RanToCompletion 当前的SynchronizationContext可能不会用作TaskScheduler - The current SynchronizationContext may not be used as a TaskScheduler 异步服务器方法中使用的SynchronizationContext - SynchronizationContext used in asynchronous server methods 从给定的线程获取SynchronizationContext - Get SynchronizationContext from a given Thread 如何创建发布到给定SynchronizationContext的任务? - How do I create Tasks that are posted to a given SynchronizationContext?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM