Reputation: 2635
I am trying to create a second thread with dispatcher so that I can have the primary dispatcher (for the UI) completely stress-free, and have the UI constantly respondant.
Now, I could create multiple threads for each sub (or void in C#), but isn't it possible for me to create one new thread and grab it's dispatcher, and invoke to that? This is what I've done:
Private CheckLoopThread As New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf CheckLoop))
CheckLoopThread.Priority = System.Threading.ThreadPriority.Lowest
CheckLoopThread.Start()
Dim Test As Windows.Threading.Dispatcher = Windows.Threading.Dispatcher.FromThread(CheckLoopThread)
However, the variable "Test" is after execution "Nothing". How is this possible? Is the another way to create a second dispatcher?
Answers are appreciated in any .NET form. Visual Basic or C#. I am working in VB.NET WPF on the .NET 4.0 framework.
Thanks in advance.
Upvotes: 15
Views: 11229
Reputation: 22038
Why locking?
I prefer:
Dispatcher myDispatcher = null;
// create a manual reset event for crossthread signalling.
var dispatcherReadyEvent = new ManualResetEvent(false);
// create a new thread.
new Thread(new ThreadStart(() =>
{
// get the current dispatcher (if it didn't exists
// it will be created.
myDispatcher = Dispatcher.CurrentDispatcher;
// set the signal that the dispatcher is created.
dispatcherReadyEvent.Set();
// run the dispatcher.
Dispatcher.Run();
})).Start();
// wait until the dispatcher is created on the thread.
dispatcherReadyEvent.WaitOne();
// run something on the dispatcher thread.
myDispatcher.Invoke(...);
Upvotes: 18
Reputation: 14956
Dispatcher.FromThread(...)
will not create a Dispatcher and will return null if a Dispatcher has not already been created for the thread. To create a Dispatcher for a thread, you will have to access Dispatcher.CurrentDispatcher
at least once on your CheckLoopThread
. As it says on MSDN for Dispatcher.CurrentDispatcher
:
If a Dispatcher is not associated with the current thread, a new Dispatcher will be created. This is not the case with the FromThread method. FromThread will return null if there is not a dispatcher associated with the specified thread
Upvotes: 13
Reputation: 675
I'm actually creating a lot of these dispatchers, I guess the proper way is something along the following lines:
object theLock = new object();
Dispatcher dispatcher = null;
lock (theLock)
{
new Thread(new ThreadStart(() =>
{
lock (theLock)
{
dispatcher = Dispatcher.CurrentDispatcher;
Monitor.Pulse(theLock);
}
Dispatcher.Run();
})).Start();
Monitor.Wait(theLock);
}
dispatcher.Invoke(...);
It seems complicated with all the locking, but theoretically the Start()
method can return before dispatcher
is actually set, so a call to to it might result in a NullReferenceException
without the locks.
Upvotes: 5