Reed Copsey, Jr. Thoughts on F#, C#, WPF, .NET, and programming for Scientific Visualization Home About Series Talks Contact Me Launching a WPF Window in a Separate Thread, Part 1 Posted by Reed on Monday, November 28, 2011 · 45 Comments Typically, I strongly recommend keeping the user interface within an applicationâ€™s main thread, and using multiple threads to move the actual â€œworkâ€ into background threads. However, there are rare times when creating a separate, dedicated thread for a Window can be beneficial. This is even acknowledged in the MSDN samples, such as the Multiple Windows, Multiple Threads* sample. However, doing this correctly is difficult. Even the referenced MSDN sample has major flaws, and will fail horribly in certain scenarios. To ease this, I wrote a small class that alleviates some of the difficulties involved. The MSDN Multiple Windows, Multiple Threads Sample* showed how to launch a new thread with a WPF Window, and will work in most cases. The sample code (commented and slightly modified) works out to the following: // Create a thread Thread newWindowThread = new Thread(new ThreadStart( () => { // Create and show the Window Window1 tempWindow = new Window1(); tempWindow.Show(); // Start the Dispatcher Processing System.Windows.Threading.Dispatcher.Run(); })); // Set the apartment state newWindowThread.SetApartmentState(ApartmentState.STA); // Make the thread a background thread newWindowThread.IsBackground = true; // Start the thread newWindowThread.Start(); This sample creates a thread, marks it as single threaded apartment state, and starts the Dispatcher on that thread. That is the minimum requirements to get a Window displaying and handling messages correctly, but, unfortunately, has some serious flaws. *Note: The referenced sample is no longer available as of 2013. A new Multithreaded Web Browser Sample shows a similar technique and code The first issue â€“ the created thread will run continuously until the application shuts down, given the code in the sample. The problem is that the ThreadStart delegate used ends with running the Dispatcher. However, nothing ever stops the Dispatcher processing. The thread was created as a Background thread, which prevents it from keeping the application alive, but the Dispatcher will continue to pump dispatcher frames until the application shuts down. In order to fix this, we need to call Dispatcher.InvokeShutdown after the Window is closed. This would require modifying the above sample to subscribe to the Windowâ€™s Closed event, and, at that point, shutdown the Dispatcher: // Create a thread Thread newWindowThread = new Thread(new ThreadStart( () => { Window1 tempWindow = new Window1(); // When the window closes, shut down the dispatcher tempWindow.Closed += (s,e) => Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background); tempWindow.Show(); // Start the Dispatcher Processing System.Windows.Threading.Dispatcher.Run(); })); // Setup and start thread as before This eliminates the first issue. Now, when the Window is closed, the new threadâ€™s Dispatcher will shut itself down, which in turn will cause the thread to complete. The above code will work correctly for most situations. However, there is still a potential problem which could arise depending on the content of the Window1 class. This is particularly nasty, as the code could easily work for most windows, but fail on others. The problem is, at the point where the Window is constructed, there is no active SynchronizationContext. This is unlikely to be a problem in most cases, but is an absolute requirement if there is code within the constructor of Window1 which relies on a context being in place. While this sounds like an edge case, itâ€™s fairly common. For example, if a BackgroundWorker is started within the constructor, or a TaskScheduler is built using TaskScheduler.FromCurrentSynchronizationContext() with the expectation of synchronizing work to the UI thread, an exception will be raised at some point. Both of these classes rely on the existence of a proper context being installed to SynchronizationContext.Current, which happens automatically, but not until Dispatcher.Run is called. In the above case, SynchronizationContext.Current will return null during the Windowâ€™s construction, which can cause exceptions to occur or unexpected behavior. Luckily, this is fairly easy to correct. We need to do three things, in order, prior to creating our Window: Create and initialize the Dispatcher for the new thread manually Create a synchronization context for the thread which uses the Dispatcher Install the synchronization context Creating the Dispatcher is quite simple â€“ The Dispatcher.CurrentDispatcher property gets the current threadâ€™s Dispatcher and â€œcreates a new Dispatcher if one is not already associated with the thread.â€ Once we have the correct Dispatcher, we can create a SynchronizationContext which uses the dispatcher by creating a DispatcherSynchronizationContext. Finally, this synchronization context can be installed as the current threadâ€™s context via SynchronizationContext.SetSynchronizationContext. These three steps can easily be added to the above via a single line of code: // Create a thread Thread newWindowThread = new Thread(new ThreadStart( () => { // Create our context, and install it: SynchronizationContext.SetSynchronizationContext( new DispatcherSynchronizationContext( Dispatcher.CurrentDispatcher)); Window1 tempWindow = new Window1(); // When the window closes, shut down the dispatcher tempWindow.Closed += (s,e) => Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background); tempWindow.Show(); // Start the Dispatcher Processing System.Windows.Threading.Dispatcher.Run(); })); // Setup and start thread as before This now forces the synchronization context to be in place before the Window is created and correctly shuts down the Dispatcher when the window closes. However, there are quite a few steps. In my next post, Iâ€™ll show how to make this operation more reusable by creating a class with a far simpler APIâ€¦ FILED UNDER .NET, C#, WPF · TAGGED WITH .NET, C#, WPF About Reed Reed Copsey, Jr. - http://www.reedcopsey.com - http://twitter.com/ReedCopsey Comments 45 Responses to “Launching a WPF Window in a Separate Thread, Part 1” Josh says: May 1, 2012 at 8:05 AM Great article Reed. Very informative and detailed. I’m anxiously awaiting part 2. Thanks, Josh Reply Robert says: July 18, 2012 at 5:47 AM You made my day, thanks a million for the background information! Cheers Robert. Reply elshev says: August 10, 2012 at 2:16 AM Thanks Reed. But what about modal windows? I can’t write tempWindow.ShowDialog(); System.Windows.Threading.Dispatcher.Run(); But it works good without Dispatcher.Run(); Should I write something like this: tempWindow.Loaded += (s, e) => Dispatcher.Run(); tempWindow.ShowDialog(); (which doesn’t work)? Or for modal windows it’s not necessary to write Dispatcher.Run(); and Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background); Reply Reed says: August 10, 2012 at 9:05 AM Typically, you wouldn’t use a Modal dialog in its own thread – if you want modal behavior, you’d use it in the UI thread. Reply DaveD says: May 13, 2014 at 6:25 AM Hi Reed, great article, thanks for offering up your expertise! The reason I’m using ShowDialog() is I put a try/catch around it as a very handy way of catching unhandled exceptions. So, I have this same question: Is the Dispatcher.Run() necessary for ShowModal()? (FYI – I need to run my UI in a separate thread because it is very large and changes often and is therefore bug-prone. The main window runs machine automation. The end result is that the UI can crash but the main window continues the machine automation.) Reply DaveD says: June 25, 2014 at 6:14 AM UPDATE – When I wrote the above I didn’t realize that processing stops at the Dispatcher.Run() , so I can wrap my try/catch around it. IMPORTANTLY I found that although ShowModal() seems to work every bit as well, I found in testing that randomly – sometimes after hours or days of operation – I’d get some weird error like protected memory violation or something like that (I forget exactly). This error disappeared after going back to Dispatcher.Run(). So this is more testimony that the method presented here by Reed is best! Reply Amokk says: October 25, 2012 at 11:35 PM InvalidOperationException. Hate you Not STAThread. Reply Gennady Vanin (Novosibirsk) says: April 24, 2013 at 9:01 PM Hello, Reed, your “Multiple Windows, Multiple Threads sample” link does not really point to used in article sample. It points to MSDN “Threading Model” (.NET 4.5) which has the section with such title and respective snippets This article has the only ref to one-window “Single-Threaded Application with Long-Running Calculation Sample” only. So, I downloaded few times that one-window sample Only if to switch the version of .NET 3.0 or 3.5 of this article, the section “Multiple Windows, Multiple Threads” has a reference to used by you sample. Though, it is called “Multithreading Web Browser Sample” and has quite different link: http://msdn.microsoft.com/en-us/library/ms771272%28v=vs.90%29.aspx Probably it would have been better to give more correct/direct references and titles… Reply Reed says: April 25, 2013 at 9:06 AM Gennady, Thank you for the updated info. When I wrote this article (in late 2011), the link and title was correct. A recent MSDN update for VS 2012 has broken it. I’ve updated the article to link to the web browser sample, and noted that the original sample is no longer available. -Reed Reply Jan S. says: August 4, 2013 at 2:34 PM Hello, how can i close Window prgrammatically? It allways says that Thread is not Thread that owns Window?! How can i do that? Thanks Reply Jan S. says: August 4, 2013 at 2:35 PM Just abort Thread wouldnÂ´t be the correct way isnÂ´t it? Reply Reed says: August 4, 2013 at 5:00 PM No, that would not be a good approach. Reply Reed says: August 4, 2013 at 5:01 PM If you’re inside the Window’s thread, that should happen. If you’re trying to close it from “outside”, you’ll need to use theWindow.Dispatcher.BeginInvoke to marshal the call to close back onto the Window’s Dispatcher/thread. Reply Jan S. says: August 5, 2013 at 12:07 AM Thanks for your answer, in relation to your example that should look like tempWindow.Dispatcher.BeginInvoke(new Action(() => tempWindow.Close())); ? Cheers Reply Reed says: August 5, 2013 at 9:57 AM Yes, though you’d also need to declare tempWindow outside of the thread’s lambda (since you’re accessing it from outside of the thread to close it). Reply Raj says: March 3, 2015 at 4:01 AM I was really struggling with closing the UI dispatched by sec thread. Ur guidelines so helpful. Thanks a lot. james says: March 18, 2019 at 4:24 AM Window.Close(); Reply winzi says: August 29, 2013 at 9:35 PM i am showing waiting icon to user in wpf app. For showing wait icon, i create a new thread and then load the icon usercontrol in that thread. If i use Dispatcher.Run() in the thread delegate then app crashes after some clicks. Reason is obvious that Dispatcher processing is not getting shut down but my view is there is no need of Dispatcher.Run in that case. What do you suggest? Reply Reed says: August 30, 2013 at 9:17 AM If you’re using this technique just to show a waiting icon, it sounds more like you need to just move your work into a background thread, and use the icon on the main UI thread. That’s the standard, preferred pattern. Reply Chris W says: October 16, 2013 at 1:04 PM Hi, thanks for the article. I was wondering what if you use styles from a ResourceDictionary defined in App.xaml? It says that “The calling thread cannot access this object because a different thread owns it.” when I’m trying to use Style=”{StaticResource UserControlFontStyle}” in a Window in the new Thread. Reply Reed says: October 16, 2013 at 1:29 PM This isn’t going to work. The application plumbing is tied to the main application class, which is going to be on the main thread. In general, your styles would need to be explicitly handled within this Window instead. Reply weima says: October 11, 2017 at 9:33 PM I know this post is long time back. i have a separate resource xaml file and load it programmingly, but still get same exception. what do you mean by headled within this window? can show show me a bit of code? Reply Reed says: October 12, 2017 at 9:56 AM Would need a lot more context – I recommend asking on StackOverflow, or even in the WPF StackOverflow chat. Feel free to ping me there if you want. Reply Ciberguille says: April 25, 2014 at 8:48 AM Hi, good article if he could see this http://stackoverflow.com/questions/23297133/launching-a-wpf-window-in-a-separate-thread, and how I could after the code executed hide this window Reply Kevin says: November 13, 2014 at 10:34 PM I tried a search, and it doesn’t look like there is a part 2. Too bad, this was a great article. Reply Michael Kosak says: March 14, 2015 at 11:01 AM I am thinking this would be a great way to implement a ‘simulator’ for test input to my program AND a GUI ‘monitor’ for whenever I am hooked up to real hardware. I have a TCP/IP connection to a device. It sends data to my program and also start/stop commands. The thread to receive this is in a background thread. I am not always hooked up to real hardware, so I needed to create simulated commands and data. So what I will do with this is create this thread with a GUI. On the GUI I will put buttons to simulate the start/stop/sendData commands for when I am not hooked up to the hardware, and use the same window to show what I am receiving when I AM hooked up. This will give us a way to see what we are getting (all the TCP/IP is plain text except for the binary data) Reply Reed says: March 14, 2015 at 2:58 PM Michael, Given that this is all async IO based, there’s no reason for two threads. You should be able to handle it in a single threaded GUI app. The other alternative, for simulations, would be a separate process, which is likely closer to working with hardware. Reed Reply Damien C. says: May 15, 2015 at 5:05 PM Was there ever a followup post “In my next post, Iâ€™ll show how to make this operation more reusable by creating a class with a far simpler APIâ€¦”? Reply Reed says: June 30, 2015 at 10:07 AM I never did write the follow up to this. Reply Richard says: June 30, 2015 at 7:19 AM At least in .NET 4.5, there’s no need to call SetSynchronizationContext – Dispatcher.Run will do that for you. Dispatcher.Run eventually calls PushFrameImpl, which sets the synchronization context to a new DispatcherSynchronizationContext at the start, and resets it in a “finally” block at the end: http://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/Threading/Dispatcher.cs,2260 Reply Reed says: June 30, 2015 at 10:06 AM Richard, If you look at the article, that’s not the issue. The problem is that the synchronization context potentially needs to be set before you create the Window, so that it’s usable within the Window’s constructor. I address this in the article, and explicitly call out that as the reason I’m creating the context manually. -Reed Reply ngm says: October 31, 2015 at 6:46 PM This is a great post, and thank you for writing it. Are there more posts (e.g. a part 2) on this topic? We are interested in using multiple GUI threads and are interested in what all the pitfalls might be. Thanks again! Reply ltbt says: November 24, 2015 at 12:06 PM Hi Reed, I’m using your approach for a while now (thanks for that!^^), and I’m having a problem rendering a window outside screen visible area. The part that’s outside visible area never gets render, so when I drag the window to visible area, that part remains white. Have you experienced something like it? Can you help me with some insight? Thanks a lot! Reply steevcoco says: August 25, 2016 at 2:32 PM … Is also useful inside of plugin-like frameworks where you wish to spawn your own “entry point” by launching a window; and just try to live within your own space by spawning from within this other framework. Reply Shakti Singh says: September 15, 2016 at 4:19 AM Dear Sir I am working on windows forum I used your code //// Create a thread //Thread newWindowThread = new Thread(new ThreadStart(() => //{ // ManagementTab tempWindow = new ManagementTab(); // tempWindow.DefaultTab = ManagementTabType.Patient; // // When the window closes, shut down the dispatcher // tempWindow.Closed += (s, e) => // Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background); // tempWindow.ShowDialog(); // // Start the Dispatcher Processing // System.Windows.Threading.Dispatcher.Run(); //})); //newWindowThread.SetApartmentState(ApartmentState.STA); //newWindowThread.Start(); Some how at Some points I am have Cross thread error let me know if you have any clue for it Thanks, Shakti Reply jb says: June 12, 2017 at 10:53 PM “In my next post” Never written? Reply ravi says: April 25, 2018 at 12:08 AM It worked fine, but when I am trying to close window by calling window.close() it is throwing exception as Calling thread cannot access this because different threads owns it. How to resolve this?? Reply Reed says: April 25, 2018 at 12:04 PM The Close call has to happen in the Window’s thread, not a different one. You need to marshal the close call to that thread. Reply Paul Ryan says: March 22, 2019 at 6:47 PM Reed, you are awesome, thanks for posting this and leaving it up! Reply vivipeng says: April 24, 2019 at 9:55 AM very good tech article. but still one concern reminding. I am using vs2017, for your final solution(use background thread / shutdown dispatcher in window closed handler), everything is fine, window closed and thread exited… but the window will still display in “Live Visual Tree” of VS. maybe it is vs bug. for the first one -not use background thread(thread not be terminate until app end), after close window, it won’t display in “Live Visual Tree” . Reply Dy says: June 14, 2019 at 7:10 PM Hi, really helpful. Im wondering how to automatically close the window started in new thread? Reply Shubham Jain says: September 18, 2020 at 12:15 PM Thanks for this article. A much valuable information. Reply Craig says: May 8, 2017 at 9:11 AM This is just fantastic. This example code along with the ‘Better WPF Circular Progress Bar’ by Sasha Barber allows me to create a progress control that runs in its own thread and can be reused by the rest of my application whenever I need it. Reply Trackbacks Check out what others are saying about this post... Displaying WPF ProgressBar window in separate thread | Jisku.com says: October 18, 2012 at 4:08 AM […] implemented my solution following this example by – Reed […] Reply How to show a WPF window from Class Library (dll) project? – program faq says: April 4, 2018 at 10:42 PM […] WPF window to existing Class Library project. Also, someone teaches you how to show the window from here. Everything look good until I tried, there is nothing shows up when I call the method […] Reply Speak Your Mind Tell us what you're thinking... and oh, if you want a pic to show with your comment, go get a gravatar! Name (required) Mail (will not be published) (required) Website Search for: Categories Categories Select Category .NET (73) C# (67) F# (4) MVVM (15) WPF (19) Algorithms (34) Async (7) Parallelism (22) C Tech (1) C++ (3) Community (3) F# Software Foundation (1) Gjallarhorn (1) Performance (2) Professional (4) Uncategorized (5) Meta Log in Entries feed Comments feed WordPress.org Tags .NET .NET 4 .NET 4.5 Algorithms Async C# C# 4 C# 5 Charity Community F# F# Software Foundation FSSF GiveCamp IDisposable Interop MEF MVP MVVM Optimization Parallelism Performance PLINQ Programming Windows Forms WPF WPF Gjallarhorn F# StackOverflow Reed Copsey 530,914 ●7272 gold badges●11031103 silver badges Archives December 2020 December 2019 December 2018 December 2017 December 2016 December 2015 December 2014 October 2013 November 2011 October 2011 September 2011 August 2011 April 2011 January 2011 December 2010 October 2010 July 2010 April 2010 March 2010 February 2010 January 2010 December 2009 November 2009 October 2009 September 2009 August 2009 July 2009 May 2009 April 2009 March 2009 Twitter Feed META Log in Entries feed Comments feed WordPress.org CAREER C Tech RECENT POSTS F# Basics – Result<'a>: or How I Learned to Stop Worrying and Love the Bind F# Basics – From loops to folds 2018 Christmas Trees – Cross Platform Edition using Avalonia CATEGORIES .NET Algorithms Async C Tech C# C++ Community F# F# Software Foundation Gjallarhorn MVVM Parallelism Performance Professional Uncategorized WPF © 2021 REED COPSEY, JR. · SHADES OF BLUE THEME BY STUDIOPRESS · WORDPRESS · LOG IN