I would like to create a subclass of DispatcherObject to create my own thread-affined objects with a message queue, like WPF uses for UI elements.
I have a test app that runs without crashing, but the DispatcherObject doesn’t seem to be processing its message queue. I just created a new blank WPF application and added this code to the MainWindow.xaml.cs:
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
DispatcherWorker worker = null;
ManualResetEventSlim latch = new ManualResetEventSlim(false);
new Thread(() => {
worker = new DispatcherWorker();
latch.Set();
}).Start();
latch.Wait();
// worker.Dispatcher.Thread is stopped by here... why?
worker.Dispatcher.BeginInvoke(new Action(() => {
// This code never executed
worker.DoWork(this);
}));
}
}
public class DispatcherWorker : DispatcherObject {
public void DoWork(MainWindow window) {
VerifyAccess();
window.Dispatcher.BeginInvoke(new Action(() => window.Background = Brushes.Black));
}
}
The DoWork() method is never executed, and if I put a breakpoint just before the call to BeginInvoke, I see that the Dispatcher’s thread is stopped. Why is it stopped? Am I setting up the thread wrong?
(This similar question seems to have the same problem, but the accepted answer says to run the code in a GUI application, which will have a message pump. But I’m getting the same problem even when running in a GUI app.)
The thread that owns the
Dispatcherwill need to “pump” thatDispatcher. That is, it will need to be told to process messages queued via thatDispatcher. To do this, you use aDispatcherFrame:This should appear after you set your latch. That thread will never exit – it will just pump messages on that thread’s dispatcher. If you want it to have an exit condition, see the documentation for the
DispatcherFrameContinueproperty.Note that it’s irrelevant whether you’re using your custom
DispatcherWorkerclass or some other built-in WPF class. If there’s nothing pumping theDispatcheron that thread, no messages will be processed.