anonymoose123

Hi,

I'm new to WPF and .NET UI programming in general.

I would like to have at least 2 threads running for the duration of my app's existence. There is the UI thread (the WPF thread), and a "model" thread (which should run for the entire length of the program).

For example, a program like iTunes I would assume has an UI thread as well as something in the background which keeps the music going. This other thread interacts with the UI, but it isn't a short-lived thread pool worker thread, it sticks around. I've read some of the documentation on BeginInvoke() on a delegate and it sounds like it's just for worker threads

I am not really sure how to get what I want. I tried out making a program with a "driver" class that spawns off the WPF application in a separate thread like so:

// Initialize GUI thread.

Thread t = new Thread(new ThreadStart(BleepDriver.StartGUIThread));

t.SetApartmentState(ApartmentState.STA);

// Start GUI.

t.Start();

After I call t.Start(), what happens to the flow in this code Can I keep calling other stuff afterwards Or does calling t.Start() transfer flow over to the WPF loop

Ideally I figured I would have the driver code spawn off the WPF thread for the UI, and then make the "model" objects and handle them itself somehow. I guess I need to add a MessageLoop somehow



Re: Windows Presentation Foundation (WPF) WPF and multithreading basics

Dwayne Need [MSFT]

Calling t.Start() just allows that thread to be scheduled on the CPU. Your thread will keep running, so yes, you can do more stuff afterwards.

I would advise the following. Create a normal WPF app, so that the main thread is running the WPF code, this will be your UI thread. Then in your code, such as OnStartup(), I would spawn a worker thread much like you show above. This will be your model thread. If your model thread needs to call methods on objects in the UI, it must ask the UI thread to do so. You can call BeginInvoke on the UI thread's Dispatcher instance. Note that this is a different method than you mention above, which is delegate.BeginInvoke(). I'm talking about Dispatcher.BeginInvoke or Dispatcher.Invoke.

The Dispatcher is a convenient little class that will implement a message loop for you. Just call Dispatcher.Run, and it will enter an infinite loop processing a queue of pending work items. Dispatcher.BeginInvoke and Dispatcher.Invoke just put work items into this queue. Dispatcher.Run will return when you call Dispatcher.InvokeShutdown().






Re: Windows Presentation Foundation (WPF) WPF and multithreading basics

anonymoose123

Thanks Dwayne, that clears this up a lot.

Does this mean that a Dispatcher is special somehow I thought an STA thread could only talk to objects made within that thread, I guess it may also talk to other threads' Dispatchers

If I wanted to communicate in the other direction too, I want my UI thread to send a message to the model's thread, I guess I just do the same thing and call Dispatcher.BeginInvoke() on the model thread's Dispatcher





Re: Windows Presentation Foundation (WPF) WPF and multithreading basics

anonymoose123

oh... and about the BeginInvoke call: this takes a delegate in. but the UI thread is STA, so how can I refer to an object on a different thread that I wish to delegate to all of the examples I can find on MSDN are very simple and just involve calling methods on the same object.

For example, say I was a music player and I had a Controller object in the "model" thread, and by pressing "play" in the UI I wanted to send a "play music" message.

I assume I would do something like:

controllerDispatcher.BeginInvoke( controller.DoPlayMusic, NULL )

I guess I can get the controller's Dispatcher from Dispatcher::FromThread(Thread) with the controller's thread, but how do I get to refer to the controller object itself in setting up the delegate "controller.DoPlayMusic" the controller object isn't owned by the UI thread.

sorry if my questions sound sort of basic, I'm just finding it hard to wrap my head around this Smile





Re: Windows Presentation Foundation (WPF) WPF and multithreading basics

Adam Smith - MSFT

It's not that you can't reference objects (such as controller, say) from other threads, it's just that you can't call methods on objects with affinity to other threads. So, for a very simple example, you could have a member variable which points to controller and retrieve the instance from any thread. If you were to actually call DoPlayMusic on other threads, you'd see an exception. This is assuming that "controller" is an instance of a type which derives from WPF's DispatchObject - if it's your own type, and you're able to ensure thread safe operations, you're free to do whatever you want on any thread - STAThread won't affect that.






Re: Windows Presentation Foundation (WPF) WPF and multithreading basics

anonymoose123

thanks Adam, makes sense



Re: Windows Presentation Foundation (WPF) WPF and multithreading basics

Adam Smith - MSFT

Cool - let us know if you have other questions.

Oh, and I meant "DispatcherObject", not "DispatchObject" above.