Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
261 views
in Technique[技术] by (71.8m points)

c# - What is the conceptual difference between SynchronizationContext and TaskScheduler

Stephen Toub blogged that

Both SynchronizationContext and TaskScheduler are abstractions that represent a “scheduler”, something that you give some work to, and it determines when and where to run that work. There are many different forms of schedulers. For example, the ThreadPool is a scheduler: you call ThreadPool.QueueUserWorkItem to supply a delegate to run, that delegate gets queued, and one of the ThreadPool’s threads eventually picks up and runs that delegate. Your user interface also has a scheduler: the message pump.

So System.Reactive.Concurrency.EventLoopScheduler, Dispatcher, ThreadPool, TaskScheduler, SyncrhonizationContext, and IScheduler implementations of Reactive Extensions are all "schedulers" in that sense.

What is the difference between them?

Why were they all necessary? I think I get EventLoop, Dispatcher, ThreadPool. IScheduler are also well explained.
But TaskScheduler and SyncrhonizationContext still not clear to me.

Stephen Cleary's excellent article explains SyncrhonizationContext, and I think I get it. Why then we needed TaskScheduler, is not clear.

Please explain or point to a source.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I was just reading CLR via C# book by Jeffrey Ritcher and thanks to him I can also give some easy explanation related to that topic. (assuming that I am not fully agreed with the whole details in answers)

First of all, TaskScheduler object is responsible for executing scheduled tasks. The FCL ships with two TaskScheduler-derived types: the thread pool task scheduler and a synchronization context task scheduler. By default, all applications use the thread pool task scheduler. This task scheduler schedules tasks to the thread pool’s worker threads. You can get a reference to the default task scheduler by querying TaskScheduler’s static Default property.

The synchronization context task scheduler is typically used for applications sporting a graphical user interface. This task scheduler schedules all tasks onto the application’s GUI thread so that all the task code can successfully update UI components like buttons, menu items, and so on. The synchronization context task scheduler does not use the thread pool at all. You can get a reference to a synchronization context task scheduler by querying TaskScheduler’s static FromCurrentSynchronizationContext method.

As you can see from SynchronizationContextTaskScheduler implementation, internally it uses SynchronizationContext field. FCL defines a base class, called System.Threading.SynchronizationContext, which solves all these problems:

  • GUI applications impose a threading model where the thread that created a UI element is the only thread allowed to update that UI element. This is a problem, because your code will throw an exception if it tries to update UI elements via a thread pool thread. Somehow, the thread pool thread must have the GUI thread update the UI elements.
  • ASP.NET applications allow any thread to do whatever it wants. When a thread pool thread starts to process a client’s request, it can assume the client’s culture, allowing the web server to return culture-specific formatting for numbers, dates, and times. In addition, the web server can assume the client’s identity,so that the server can access only the resources that the client is allowed to access. When a thread pool thread spawns an asynchronous operation, it may be completed by another thread pool thread, which will be processing the result of an asynchronous operation. While this work is being performed on behalf of the original client request, the culture and identity needs to “?ow” to the new thread pool thread so any additional work done on behalf of the client is performed using the client’s culture and identity information.

Simply stated, a SynchronizationContext-derived object connects an application model to its threading model. The FCL defnes several classes derived from SynchronizationContext, but usually you will not deal directly with these classes; in fact, many of them are not publicly exposed or documented.

For the most part, application developers do not need to know anything about the SynchronizationContext class. When you await a Task, the calling thread’s SynchronizationContext object is obtained. When a thread pool thread completes the Task, the SynchronizationContext object is used, ensuring the right threading model for your application model. So, when a GUI thread awaits a Task, the code following the await operator is guaranteed to execute on the GUI thread as well, allowing that code to update UI elements. For an ASP.NET application, the code following the await operator is guaranteed to execute on a thread pool thread that has the client’s culture and principal information associated with it.

You can, of course, define your own class derived from TaskScheduler if you have special task scheduling needs. Microsoft has provided a bunch of sample code for tasks and includes the source code for a bunch of task schedulers in the Parallel Extensions Extras package. Like, IOTaskScheduler, LimitedConcurrencyLevelTaskScheduler, OrderedTaskScheduler, PrioritizingTaskScheduler, ThreadPerTaskScheduler.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...