How to start a UI thread in C#

15,757

Solution 1

Use Application.Run - it starts a message loop in the current thread. There are overloads to take a form to start with, or an application context, or neither. (If you want to do this for a new thread, you need to create the thread and start it in the normal way, and make it call Application.Run.)

Solution 2

If you are interested in using WPF, check out MSDN's article WPF's Threading Model, in particular the "Multiple Windows, Multiple Threads" section. It details what you need to do to create a new Dispatcher and show a window on a new thread.

Solution 3

If you're looking to create a new thread that is capable of creating and dealing with Window handles, then you can use the SetApartmentState function on the Thread object and set it to STA. You'll also likely need to call Application.Run inside the method for this thread in order to create your message loop. However, bear in mind that you're subject to the same cross-threading no-no's that you have in any other thread (ie, you can only interact with the handle for a control on the thread inside which it was created), so you can't do anything on your other UI thread without switching contexts.

Share:
15,757
Filip Frącz
Author by

Filip Frącz

I'm a Chicago-based software engineer specializing in high frequency trading applications. Currently employed at Chicago Trading Company. Previously I worked at Thomson Reuters and Trading Technologies on mobile and TT SDK for the next-gen Debesys aka TT trading platform. C++, C#, Java, Microservices

Updated on July 27, 2022

Comments

  • Filip Frącz
    Filip Frącz almost 2 years

    I know I can start a new worker thread from with .NET. But how do I start a new UI thread (like in MFC)?

    I don't mind if the solution is restricted to Windows boxes only; I also would like the solution to be purely .NET - no p/invokes to CreateThread, etc.

    Any input appreciated.

  • supercat
    supercat over 12 years
    How does Application.Run compare with ShowDialog, which is the approach I've been using before?
  • Jon Skeet
    Jon Skeet over 12 years
    @supercat: Are you calling ShowDialog from a non-UI thread then? I'm not sure of the effect in that case.
  • supercat
    supercat over 12 years
    Yeah, I'm calling ShowDialog from a non-UI thread; the apparent effect is that the new window thus created will have a UI thread independent from the UI thread of any other window. It seems to work well provided that the window doesn't try to interact with any controls on other threads, and provided that it doesn't try to set its MdiParent to a window running on another thread.
  • Jon Skeet
    Jon Skeet over 12 years
    @supercat: Have you checked whether it runs a message loop in the calling thread, or just creates a new UI thread and blocks the calling thread until the window has finished?
  • supercat
    supercat over 12 years
    The new window will be responsive even if the main UI thread is blocked, and blocking the new window's UI thread will not affect the main window. I think there may be some issues with things like the clipboard, but mainly I've used this approach for things like progress-update or status windows (e.g. if I have a control display a whirligig in both the main UI window and another window on a different thread, I can visually distinguish between things like garbage-collection which block all threads, and operations which momentarily block the UI thread but let other threads run.
  • Jon Skeet
    Jon Skeet over 12 years
    @supercat: I was talking about the thread that you launched called ShowDialog on - do you know whether that is blocked and a new thread started, or whether it's used directly?
  • supercat
    supercat over 12 years
    The thread that calls ShowDialog() will not return from the ShowDialog() call until the form is closed. The code that called ShowDialog() is then responsible for disposing the form.
  • Jon Skeet
    Jon Skeet over 12 years
    @supercat: Right - but I believe that ShowDialog will start a new UI thread. Whereas with Application.Run, the existing thread is used for the message loop (and it disposes of the form itself). But in most cases the new thread wouldn't be important anyway.