In programming, complex operations are often performed in a button, and the value returned after a complex operation is added to a candidate in listview or ComboBox. This timeProgramCard, when the programmer puts these cardsCodeAfter being put into the thread, it is found that when you operate on the control"Inter-thread operation is invalid: access from a thread that is not creating a control" exception.
It is advantageous that. Net does not allow us to operate controls across threads. Because if you have more threads, when two threads try to change a control to the desired state at the same time, the thread deadlock will occur. But is it because of this reason that we can only get the program stuck?Of course not.
Solution (1): Use backgroundworker
Official reference: http://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker (vs.80). aspx
The backgroundworker class allows you to run operations on individual dedicated threads. Time-consuming operations (such as downloads and database transactions) may cause the user interface (UI) to stop responding after a long time of running. You can use the backgroundworker class to solve the problem easily if you need a user interface that can respond and face long delays related to such operations.
To set background operations, add an event handler for the dowork event. This event handler calls time-consuming operations. To start this operation, call runworkerasync. To receive a progress update notification, handle the progresschanged event. To receive a notification when the operation is complete, handle the runworkercompleted event.
Make sure that you do not operate any user interface objects in the dowork event handler. You should use the progresschanged and runworkercompleted events to communicate with the user interface.
Backgroundworker events are not sent across appdomain boundaries. Do not use the backgroundworker component to perform multi-threaded operations in multiple AppDomains.
Note: You need to call the backgroundworker1.runworkerasync (); Method to start
Common Methods:
1. runworkerasync
Start background operations. Trigger a dowork event
2. cancelasync
Cancels the pending background operation.
Note: This method sets the cancellationpending attribute to true and does not terminate background operations. In background operations, you must check the cancellationpending attribute to determine whether to continue time-consuming operations.
3. reportprogress
Raise the progresschanged event.
Common attributes
1. cancellationpending
Indicates whether the application has requested to cancel background operations.
Read-only attribute. The default value is false. If the cancelasync method is executed, the value is true.
2. workersuppscanscancellation
Indicates whether asynchronous cancellation is supported. To execute the cancelasync method, you must first set this attribute to true.
3. workerreportsprogress
Indicates whether progress can be reported. To execute the reportprogress method, you must first set this attribute to true.Required
Common events
1. dowork
The runworkerasync method is called.
2. runworkercompleted
The background operation has been completed, canceled, or thrown an exception.
3. progresschanged
The reportprogress method is called.
In the dowork event handler, no user interface objects are operated. You should use the progresschanged and runworkercompleted events to communicate with the user interface.
If you want to communicate with the control on the user interface in the dowork event handler, you can use the reportprogress method.
Reportprogress (INT percentprogress, object userstate), you can pass an object.
The progresschanged event can be retrieved from the progresschangedeventargs parameter.Class userstate property to get this information object.
Simple programs use backgroundworker, which is easier to communicate with the control on the user interface than thread. Therefore, you need to use a delegate to call the control's invoke or begininvoke method, which is convenient without backgroundworker.
For more information, see C # backgroundworker.
For example:
(1) In the form_load event, start backgroundworker
Private void BP neural network model training _ load (Object sender, eventargs E)
{
Backgroundworker1.runworkerasync ();
}
Example with parameters: backgroundworker1.runworkerasync (textbox1.text );
(2) set the dowork event of backgroundworker and start mainprocess (); function. Note: This function cannot contain the code of the operation form interface. Otherwise, an exception is thrown and should be placed in the progresschanged or runworkercompleted event.
Private void backgroundworker=dowork (Object sender, doworkeventargs E)
{
Mainprocess ();
}
Example of parameters: String url = E. argument. tostring ();
(3) report progress at some time points in the mainprocess () function.
If you want to communicate with the control on the user interface in the dowork event handler, you can use the reportprogress method.
Reportprogress (INT percentprogress, object userstate), you can pass an object.
The progresschanged event can be retrieved from the progresschangedeventargs parameter.Class userstate property to get this information object.
One parameter: backgroundworker1.reportprogress (3); // The End Of The training sample
Two parameters: bw. reportprogress (I * 100/10, I );
(4) Handling progress and operation interface in the backgroundworkerprogress progresschanged event
One parameter:
Private void backgroundworker1_progresschanged (Object sender, progresschangedeventargs E)
{
If (E. progresspercentage = 1)
Label3.text = "preparing sample data! ";
If (E. progresspercentage = 2)
Label3.text = "the sample is being trained. It may take a long time. Please wait! ";
If (E. progresspercentage = 3)
Label3.text = "The training sample is over! ";
}
(5) set workerreportsprogress to true. The default value is false. Otherwise, an exception occurs.
Two parameters:
Progressbar1.value = E. progresspercentage;
Label1.text = E. userstate. tostring ();
FAQ: How to pass multiple parameters?
A: reportprogress (INT percentprogress, object userstate) has two parameters: Progress and object ), we can customize a struct or class as this parameter to pass multiple variables. Take struct as an example:
(1) define struct
Struct usestatestruct
{
Public int;
Public Double B;
Public usestatestruct (int A, double B)
{
This. A =;
This. B = B;
}
}
(2) Transfer struct
Usestatestruct US = new usestatestruct (study, BP. E); // custom
Backgroundworker1.reportprogress (4, US );
(3) extract struct data
Usestatestruct US = (usestatestruct) E. userstate; // convert the following type:
Textbox1.text = us. A. tostring ();
Textbox2.text = us. B. tostring ();
Solution (2): Delegate
Http://msdn.microsoft.com/zh-cn/library/900fyy8e (vs.80). aspx
Refer:
Teach you how to solve the problem of "invalid inter-thread operations: access it from a thread that is not creating a control"