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();
}
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.
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.
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).
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With