After having read the documentation for the Dispatcher
class, I realize that it can be used for non-UI queueing of actions too.
So how does the Dispatcher
class actually works? I'm aware of that, it's main job is to queue actions to a specific thread - but how does it "send" those actions to the thread? And how do the thread "get" these actions?
My best guess is that there's some kind of "thread queue" for each thread, but then again I've got no idea.
A Dispatcher is a professional who ensures that everything runs smoothly by coordinating with customers, providing precise logistics for drivers to follow along on their routes, and coordinating delivery times. Dispatchers are the point of contact for drivers and have all the information needed to make deliveries.
Dispatch is a procedure for assigning employees (workers) or vehicles to customers. Industries that dispatch include taxicabs, couriers, emergency services, as well as home and commercial services such as maid services, plumbing, HVAC, pest control and electricians.
It is not a trivial task to get one thread to initiate execution of code onto another thread. The crux of the problem is that you cannot simply tell any thread to start executing a method after that thread has already started. The target thread has to be specifically setup to receive these kind of requests ahead of time.
The usual pattern used is the producer-consumer. The target thread will spin around an infinite loop waiting for messages to appear in a blocking queue. The queue is designed to block until an item appears in the queue thus preventing the target thread from consuming CPU time unnecessarily. Here is a really simple way to get a thread to accept the injection of a delegate for execution.
public class Example
{
private BlockingCollection<Action> queue = new BlockingCollection<Action>();
public Example()
{
new Thread(
() =>
{
while (true)
{
Action action = queue.Take();
action();
}
}).Start();
}
public void ExecuteAsync(Action action)
{
queue.Add(action);
}
}
Now, in the case of a UI thread it already has a message loop running so the Dispatcher
class can simply post a special message to the message queue containing the delegate to be executed. In the middle of processing all of the paint, button clicks, etc. this special message will be picked up by the UI thread as well and it will begin executing the delegate.
So how does the Dispatcher class actually works? I'm aware of that, it's main job is to queue actions to a specific thread - but how does it "send" those actions to the thread?
By queuing a delegate into a queue that the target thread monitors.
And how do the thread "get" these actions?
By running an infinite loop that monitors the queue. The queue is usually a special type called a blocking queue which blocks the consuming thread if the queue is empty.
My best guess is that there's some kind of "thread queue" for each thread, but then again I've got no idea.
Pretty close. Except that threads do not actually have a built in queue for this purpose. It has to be manually setup. That is why only threads that are specifically designed can accept delegate injections. UI threads are setup this way because Application.Run
creates the message loop. In my example you will see that I had to use BlockingCollection
and an infinite loop to get it to work on a worker thread.
Well, apparently the Dispatcher queuing implementation looks like a Win32 message pump but it's not (although it uses the same User32 messages and threading model).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With