1

Actually I want to have one dedicated worker thread for handling events from both main and other worker threads. This thread must also be able to invoke delegates in other threads. (The thread receives commands from the main thread, executes some of them in other worker threads, processes the completion and progress events from these commands, and inform the main thread about how he is doing).

All this could be done manually by implementing an analogue of the message queue from delegates in the desired thread. However, I would prefer a higher level approach if such exists. From the documentation I got the impression that the Dispatcher class is well suited for this purpose. I also got feeling that an object of this class can be created in any thread, but didn't find any example. Is my feeling wrong?

Ilia
  • 425
  • 2
  • 10
  • 1
    Message queue libraries [do exist](https://stackoverflow.com/q/1529281/102937). – Robert Harvey Oct 03 '20 at 18:46
  • [`Dispatcher.CurrentDispatcher`](https://learn.microsoft.com/en-us/dotnet/api/system.windows.threading.dispatcher.currentdispatcher?view=netcore-3.1) – Pavel Anikhouski Oct 03 '20 at 18:46
  • @TheodorZoulias Thank you very much. Now I see that this is the only correct approach. If you reword your comment as answer, I'll accept it. – Ilia Oct 05 '20 at 06:26
  • My pleasure Ilia! I thought that it was a bit too trivial to post it as an answer. But if it answers your question sufficiently, here you have it. :-) – Theodor Zoulias Oct 05 '20 at 09:49
  • https://learn.microsoft.com/en-us/dotnet/standard/collections/thread-safe/blockingcollection-overview – Hans Passant Oct 05 '20 at 13:06

1 Answers1

1

There is nothing built-in, but it is quite easy to create a custom TaskScheduler that schedules work on a specific thread. Most implementations use the handy BlockingCollection class as a queue. Here is one implementation, and here is another one. You could customize any of these implementations to your needs, and then use it like this:

var myScheduler = new SingleThreadTaskScheduler();
var task = Task.Factory.StartNew(() => DoSomething(), default,
    TaskCreationOptions.None, myScheduler);

There is also the option to use the fancy TaskFactory class, so that you can start tasks on this scheduler with less code:

var myFactory = new TaskFactory(new SingleThreadTaskScheduler());
var task = myFactory.StartNew(() => DoSomething());

Personally I am not a fan of this class, because it makes me confused with the similarity between TaskFactory and the Task.Factory property.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104