I have found plenty of resources for how to invoke a function on the UI thread, but I have some logic that is only allowed to be run from the Main Thread. Is there a way to grab a dispatcher on the Main thread and invoke on it?
-
6The UI thread should be the main thread in any sensible program. – Servy May 14 '15 at 20:54
-
1Only if the main thread is running something that lets you post delegates to it (such as a message loop). – SLaks May 14 '15 at 20:55
-
1How is your main thread structured? what is it doing at the time you want the function to be invoked? – Amit May 14 '15 at 20:57
-
It's busy doing work, but I'm fine with an async invoke. the function does not need to execute immediately. also, MainThread and the WPF Thread are always seperate. – Psymunn May 14 '15 at 21:00
-
1Would it be okay if it happens sometime in the future? – Amit May 14 '15 at 21:01
-
yes, it would. i'm fine with an Aysnc call – Psymunn May 14 '15 at 21:02
-
1@Psymunn Rather than creating a new thread to be your UI thread and then leaving the main thread to go do other work, why not make your main thread your UI thread and have the other thread that you create go do whatever work your main thread was doing? – Servy May 14 '15 at 21:03
-
@Servy is right...they used to be referred to as worker threads...many people still call them that – waltmagic May 14 '15 at 22:14
-
The problem is I don't have control of that part of the architecture. The program runs code on the thread started by the codes main entry point (after that thread launches the WPF thread). It looks like I need to check if the main thread has a command queue, or add one. – Psymunn May 14 '15 at 22:50
-
@Psymunn Is that not the part of the architecture that you have no control over? If you can modify it to add in a message pump why can you not modify it to do its work in a new thread, leaving the main thread to be the UI thread? – Servy May 15 '15 at 13:51
-
Apparently this is a side effect of a third party library we use. It's a bit hackey, but my understanding is it's a way to maintain thread is to ensure we only preform actions the 3rd party library can see as the same thread as it because we aren't able to use traditional locks. The queue system won't viloate this (it can just execute jobs between calls to the 3rd party library). Right or wrong, it's the way it is. – Psymunn May 15 '15 at 15:04
3 Answers
The "dispatcher" is a concept specific to a particular UI framework (here: WPF). There is no dispatcher you can use to target any thread. Imagine the following thread:
while (true) Console.WriteLine("x");
How are you going to invoke something on that thread? It can't be done because that thread is forever busy doing something else. It is not cooperating.
I kind of doubt that you need to invoke something on the "main thread". But I'll answer the question literally. You need to make the main thread cooperate and accept work from other threads. Maybe a queue of Action
or a boolean flag that tells that thread to do something specific.

- 168,620
- 35
- 240
- 369
-
Thanks. I'll check the API to see if there's some static queue I can access to queue up tasks for the Main thread. I know it seems a little strange, but yes, it is indeed the requirement. – Psymunn May 14 '15 at 21:25
You can use a combination of signaling + data structures. Define a variable to hold details of a required function call (maybe a struct with parameters), and have your main thread periodically test if a call is required. Make sure to lock necessary objects the handle multi-threading pitfalls. You can also have a signaling object and have the initiator Monitor.Wait
on it and the main thread will signal when the function is done.

- 45,440
- 9
- 78
- 110
Edit: The program the OP questioned about did in fact have separate UI and Main threads...
You can create new threads/tasks anytime you want using
tokenSource = new CancellationTokenSource();
token = tokenSource.Token;
Task.Factory.StartNew(() =>
{
doSomeWork();
}, token);
The token is used so you can cancel the task. If something goes wrong or the task hangs, you can cancel it. You may have already read about TPL libraries but if not, do and see if it works for what you are wanting to do.
To make my answer a little more complete I wanted to add this...I am not sure this may or may not work in your case but in normal cases you would do something like this to update or work with objects in the main thread from the worker thread.
private void doSomeWork()
{
// do work here -->
if (someObject.InvokeRequired)
{
someObject.BeginInvoke((Action)delegate() { someObject.Property = someValue; });
}
else
{
someObject.Property = someValue;
}
}

- 631
- 2
- 9
- 22
-
Unfortunately I do not have control of the architecture. The UI thread is named WPF Thread and is launchde from Main Thread (which is the thread with the entry point `public static void Main(string[] args)` – Psymunn May 14 '15 at 21:13
-
1I feel your pain...Sorry I wasn't of more help. Good luck with your project. – waltmagic May 14 '15 at 22:20