Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple UI Threads - Winforms

I want to create multiple UI threads in my application. I have simulated the scenario as below. I am creating a new window / form on a button click in a background thread

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var thread = new Thread(() =>
            {
                Form f = new Form();
                Application.Run(f);
            });

            // thread.IsBackground = true; -- Not required. See Solution below
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }
    }  
}

Note that - I am doing IsBackground = true bacause when the user closes on the main form, the child forms/windows should also close down. Is there a more cleaner/graceful way to achieve the same ?

EDIT - I want to create dedicated UI threads for each window. I will have 10 such windows displaying real-time data in parallel.

Solution - Is this fine ? (as per msdn and Hans' comments below) have set the Apartment state (see code above)

protected override void OnClosed(EventArgs e)
{
    Application.Exit();
}
like image 982
Angshuman Agarwal Avatar asked Sep 27 '11 11:09

Angshuman Agarwal


People also ask

Can there be multiple UI threads?

There is no such thing as "multiple UI threads". You can only ever have one, the thread that's created when your application starts. That is the only thread that can touch the user interface and its controls. In your case, you use Invoke from a second thread to tell the UI thread to run code, not the other way around.

Is Winforms multithreaded?

A number of tools are available for multithreading your Windows Forms controls, including the System. Threading namespace, the Control. BeginInvoke method, and the BackgroundWorker component. The BackgroundWorker component replaces and adds functionality to the System.

Is Winforms single threaded?

The answer is yes, although it's infrequently done. You can have a distinct thread for each form (although each control would only have one associated UI thread).


2 Answers

Messing with threads will only bite you sooner or later.

From MSDN:

Controls in Windows Forms are bound to a specific thread and are not thread safe. Therefore, if you are calling a control's method from a different thread, you must use one of the control's invoke methods to marshal the call to the proper thread

You can of course use as many threads as you like, but don't try to create a workaround to be able to use different threads for updating the UI. Use Invoke/InvokeRequired from your worker/background threads instead.

Using an extension method makes it cleaner: Automating the InvokeRequired code pattern

like image 175
jgauffin Avatar answered Sep 22 '22 03:09

jgauffin


I think you will need to set the apartment state of your thread to single threaded as indicated here ApartmentState for dummies and here Thread-safe Form.Show: t.SetApartmentState(ApartmentState.STA). I don't know if that's possible on a background thread though.

Another thing that I would urge you to look at is MDI (multiple document interface, e.g. here). Do you really need different forms display as an own window or are they rather documents inside a common form? You may have of course a reason to create multiple UI threads.

like image 36
Andreas Avatar answered Sep 18 '22 03:09

Andreas