Summary: "The Inter-thread operation is invalid: access from the thread that is not creating the control" error Solution

Source: Internet
Author: User
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 time Program Card, when the programmer puts these cards Code After being put into the thread, it is found that when the control is operated, the "Inter-thread operation is invalid: access from a thread that is not creating the control" exception occurs.
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. Here is a solution: Use backgroundworker
Here we use an instance to tell you how to use backgroundworker.
First, define a backgroundworker. You can drag one on the panel or manually define one. This . Backgroundworker_combo =   New System. componentmodel. backgroundworker (); // Define a backgroundworker
This . Backgroundworker_combo.workersuppscanscancellation =   True ; // Set whether the task can be canceled
This . Backgroundworker_combo.dowork + =   New System. componentmodel. doworkeventhandler ( This . Backgroundworker_combo_dowork ); // What does backgroundworker do?
This . Backgroundworker_combo.runworkercompleted + =   New System. componentmodel. runworkercompletedeventhandler ( This . Backgroundworker_combo_runworkercompleted ); // Events that occur after the backgroundworker is finished

If it is dragged from the Panel, double-click the dowork event to add the code that you want to execute in the background thread, that is, the code that may cause your cards.
Then double-click the runworkercompleted event to add the code you want to operate on the control.
Here is a development example, which is similar to the implementation of the drop-down list in Google search. The idea is to search the database in dowork and put the searched items in completed.
This document requires a backgroundworker and a ComboBox control.

Static   Char X;
/**/ /**/ /**/ /// <Summary>
///Accept items found from DLL
/// </Summary>
Private   String [] Global_listitem;

Private   Void Backgroundworker_combo_runworkercompleted ( Object Sender, runworkercompletedeventargs E)
{ // If there is something in the array, add ComboBox
If (Global_listitem.length > 0 )
{
This. Combobox_app.items.clear ();
This. Combobox_app.items.addrange (global_listitem );
}
}

Private   Void Backgroundworker_combo_dowork ( Object Sender, doworkeventargs E)
{
Global_listitem=Form_setting.global_dbc.similarfilter (X );//This is a DLL method used to search for all projects with X headers and put them in an array.
}

Private   Void Combobox_app_textchanged ( Object Sender, eventargs E)
{ // When you type a letter, go to the database for query.
ComboBox CB = Sender As ComboBox;
If (Cb. Text. Length = 1 )
{
X=CB. Text [0];
This. Backgroundworker_combo.runworkerasync ();
}
}

 

 

So can't I use thread? In fact, it is not. Net also has thread-safe control access.

 

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: "it is never accessed by the thread that creates the control name of the control."

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.
Note:
You can disable this exception by setting the value of the checkforillegalcrossthreadcils attribute to false. This causes the control to run in the same way as in Visual Studio 2003.

The following code example demonstrates how to call a Windows form control from a third thread in the thread-safe and non-thread-safe mode. It demonstrates a non-thread-safe setting Control Attribute method. It also shows two methods to set the text attribute in thread-safe mode.

 using system; using system. componentmodel; using system. threading; using system. windows. forms; namespace crossthreaddemo {public class form1: FORM {// proxy Implement Asynchronous call to set the Textbox Control text attribute delegate void settextcallback (string text ); // This thread is used to demonstrate the thread security and non-security methods to call a Windows form control private thread demothread = NULL; // This background worker (backgroundworker) it is used to demonstrate the preferred method for performing asynchronous operations: Private backgroundworker backgroundworker1; private textbox textbox1; Private button settextunsafebtn; private button settextsafebtn; private button settextbackgroundworkerbtn; private system. componentmodel. icontainer components = NULL; Public form1 () {initializecomponent ();} protected override void dispose (bool disposing) {If (disposing & (components! = NULL) {components. dispose ();} base. dispose (disposing);} // This event handle creates an IE thread to call a Windows form control private void settextunsafebtn_click (Object sender, eventargs e) {This. demothread = new thread (New threadstart (this. threadprocunsafe); this. demothread. start () ;}// this method is executed in the worker thread and unsafe call is made to the Textbox Control 
Private void threadprocunsafe () {This. textbox1.text = "this text was set unsafely. ";}// this event handle creates a thread private void settextsafebtn_click (Object sender, eventargs E) that calls the Windows Forms control in thread-safe mode. {This. demothread = new thread (New threadstart (this. threadprocsafe); this. demothread. start () ;}// this method is executed in the worker thread and the Textbox Control is thread-safe to call private void threadprocsafe () {This. settext ("this text was set safely. ") ;}/// this method demonstrates a thread-safe call mode for Windows form controls. /// if the call thread is different from the thread used to create a Textbox Control, this method creates // proxy settextcallback and calls it asynchronously through the invoke method. // if it is the same, set the private void settext (string text) attribute of the text directly) {// invokerequired needs to compare the call thread ID and creation thread ID. // if they are different, trueif (this. textbox1.invokerequired) {settextcallback d = new settextcallback (settext); this. invoke (D, new object [] {text});} else {This. textbox1.text = text ;}} // The Event handle calls runworkerasync to enable the form's backgroundworker // when the backgroundworker triggers the runworkercompleted event, the text attribute of the textbox // control is set to private void settextbackgroundworkerbtn_click (Object sender, eventargs e) {This. backgroundworker1.runworkerasync ();} // This event handle sets the text attribute of the Textbox Control, which is called in the thread that creates the Textbox Control, therefore, its call is thread-safe. // backgroundworker is the preferred method for executing asynchronous operations. Private void backgroundworkerappsrunworkercompleted (Object sender, runworkercompletedeventargs e) {This. textbox1.text = "this text was set safely by backgroundworker. ";}# region windows Form Designer generated codeprivate void initializecomponent () {This. textbox1 = new system. windows. forms. textbox (); this. settextunsafebtn = new system. windows. forms. button (); this. settextsafebtn = new system. windows. forms. button (); this. settextbackgroundworkerbtn = new system. windows. forms. button (); this. backgroundworker1 = new system. componentmodel. backgroundworker (); this. suspendlayout (); // textbox1 // This. textbox1.location = new system. drawing. point (12, 12); this. textbox1.name = "textbox1"; this. textbox1.size = new system. drawing. size (240, 20); this. textbox1.tabindex = 0; // settextunsafebtn // This. settextunsafebtn. location = new system. drawing. point (15, 55); this. settextunsafebtn. name = "settextunsafebtn"; this. settextunsafebtn. tabindex = 1; this. settextunsafebtn. TEXT = "unsafe call"; this. settextunsafebtn. click + = new system. eventhandler (this. settextunsafebtn_click); // settextsafebtn // This. settextsafebtn. location = new system. drawing. point (96, 55); this. settextsafebtn. name = "settextsafebtn"; this. settextsafebtn. tabindex = 2; this. settextsafebtn. TEXT = "safe call"; this. settextsafebtn. click + = new system. eventhandler (this. settextsafebtn_click); // settextbackgroundworkerbtn // This. settextbackgroundworkerbtn. location = new system. drawing. point (177, 55); this. settextbackgroundworkerbtn. name = "settextbackgroundworkerbtn"; this. settextbackgroundworkerbtn. tabindex = 3; this. settextbackgroundworkerbtn. TEXT = "Safe BW call"; this. settextbackgroundworkerbtn. click + = new system. eventhandler (this. settextbackgroundworkerbtn_click); // backgroundworker1 // This. backgroundworker1.runworkercompleted + = new system. componentmodel. runworkercompletedeventhandler (this. backgroundworkerappsrunworkercompleted); // form1this. clientsize = new system. drawing. size (268, 96); this. controls. add (this. settextbackgroundworkerbtn); this. controls. add (this. settextsafebtn); this. controls. add (this. settextunsafebtn); this. controls. add (this. textbox1); this. name = "form1"; this. TEXT = "form1"; this. resumelayout (false); this. extends mlayout () ;}# endregion [stathread] Static void main () {application. enablevisualstyles (); application. run (New form1 ());}}}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.