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

匆匆过客 提交于 2019-11-28 08:10:27

How can I obtain a Task, that actually runs an action but is dispatched using 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

Look at the article It's All About the SynchronizationContext by Stephen Cleary.

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. For example, TPL commonly uses parent/child tasks, but async/await does not.

TPL uses task schedulers to execute its tasks. As Dennis pointed out, TaskScheduler.FromCurrentSynchronizationContext will give you a task scheduler that uses Post on the current SynchronizationContext to execute its task.

async/await usually does not use task schedulers. 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). 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). When the async method resumes, it resumes executing in that context.

Dennis pointed out the TPL way of scheduling a task to the current SynchronizationContext, but in async/await world, that approach isn't necessary. Rather, you can explicitly schedule tasks to the thread pool via 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. I have a little more information on my blog, but all the important bits are in the MSDN article. Many types use AsyncOperation rather than SynchronizationContext directly; the best documentation for this is buried under the EAP docs (section "Threading and Context"). 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!