This article explains how to use Windows Form Controls in. NET safely with multiple threads.
When using multithreading to Improve the Performance of Windows Forms applications, you must call the control in thread-safe mode.
Access to Windows Forms controls is not thread-safe in nature. If two or more threads operate on the status of a control, the control may be forced to enter an inconsistent state. Other thread-related bugs may also occur, including contention and deadlocks. It is important to ensure that controls are accessed in a thread-safe manner.
. NET Framework helps detect this issue when accessing controls in a non-thread-safe manner. When running an application in the debugger, if a thread other than the thread that creates a control tries to call the control, the debugger will throw an InvalidOperationException and prompt the message "never create a controlControl nameThe thread to access it ."
This exception occurs reliably during debugging and in some cases during runtime. We strongly recommend that you fix this issue when this error message is displayed. This exception may occur when you debug applications written in. NET Framework before. NET Framework 2.0. You can set the value of the checkforillegalcrossthreadcils attribute
FalseTo disable this exception. This causes the control to run in the same way as in Visual Studio 2003.
The non-thread-safe call Method for Windows Form Controls is directly called from the auxiliary thread. When an application is called, the debugger triggers
InvalidOperationException, Warning that the call to the control is not thread-safe. This exception occurs when multiple threads are used.
Sample Code
Private void setTextUnsafeBtn_Click (object sender, EventArgs e)
{
This. demoThread = new Thread (new ThreadStart (this. ThreadProcUnsafe ));
This. demoThread. Start ();
}
// Thread unsafe mode
Private void ThreadProcUnsafe ()
{
This. textBox1.Text = "This text was set unsafely .";
}
Make thread-safe calls to Windows Forms controls
Query the InvokeRequired property of the control.
IfInvokeRequiredReturnTrueThe actual call control delegate is used to call Invoke.
IfInvokeRequiredReturnFalseTo directly call the control.
In the following code example, the logic is calledSetText. NameSetTextDelegateDelegate type EncapsulationSetTextMethod.TextBoxControlInvokeRequiredReturnTrue,SetTextMethod CreationSetTextDelegateAnd callInvokeMethod. This makesSetTextMethod createdTextBoxControl thread calls, and will be directly set in this thread ContextTextAttribute.
Sample Code
Private void setTextSafeBtn_Click (object sender, EventArgs e)
{
This. demoThread = new Thread (new ThreadStart (this. ThreadProcSafe ));
This. demoThread. Start ();
}
// Thread-Safe Mode
Private void ThreadProcSafe ()
{
This. SetText ("This text was set safely .");
}
Sample Code
Private void SetText (stringtext)
{
If (this. textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else{
this.textBox1.Text = text;
}
}
Secure thread call using BackgroundWorker
The first choice for implementing multithreading in applications is to use the BackgroundWorker component.BackgroundWorkerThe component uses the event-driven model to implement multithreading. The auxiliary thread runs the DoWork event handler, and the control creation thread runs the ProgressChanged and RunWorkerCompleted event handlers. Be sure notDoWorkThe event handler calls any of your controls.
The following code example does not asynchronously execute any work, so there is noDoWorkThe implementation of the event handler.TextBoxControlTextAttribute inRunWorkerCompletedDirectly set in the event handler.
Sample Code
Private void setTextBackgroundWorkerBtn_Click (object sender, EventArgs e)
{
this.backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
{
this.textBox1.Text = "This text was set safely by BackgroundWorker.";
}