Winform sub-thread modify main thread (ui thread) control [Z]

Source: Internet
Author: User

Original http://www.cnblogs.com/SkySoot/archive/2012/03/14/2396552.html

Let's take a look at a piece of running will throwInvalidoperationexceptionAbnormalCodeSection:

 
Public Partial ClassTestthread: Form

 
{

 
PublicTestthread ()

 
{

 
Initializecomponent ();

 
}

 
 

 
Thread thread;

 
 

 
VoidSettext (StringStr)

 
{

 
This. Textbox1.text = STR;

 
}

 
 

 
VoidDosomething ()

 
{

 
// Do ......

 
Settext ("XXX");

 
}

 
 

 
Private VoidButtonx1_click (ObjectSender, eventargs E)

 
{

 
Thread =NewThread (NewThreadstart (dosomething ));

 
Thread. isbackground =True;

 
Thread. Start ();

 
}

 
}

In vs2005 or later versions, this error is thrown if you access the properties of a control not on the control creation thread (generally the main UI thread, the solution is to use the invoke and begininvoke provided by the control to send the call mails back to the UI thread, that is, to let the control attribute be modified and executed on the UI thread.

The following code is correctly called after modification:

The direct modification method is as follows:

 
Public Partial ClassTestthread: Form

 
{

 
Delegate VoidChangetextboxvalue (StringStr );// Add a delegate proxy

 
 

 
PublicTestthread ()

 
{

 
Initializecomponent ();

 
}

 
 

 
Thread thread;

 
 

 
VoidSettext (StringStr)

 
{

 
This. Textbox1.text = STR;

 
}

 
 

 
VoidDosomething ()

 
{

 
// Do ......

 
This. Begininvoke (NewChangetextboxvalue (settext ),"XXX");// This. Invoke call is also available.

 
}

 
 

 
Private VoidButtonx1_click (ObjectSender, eventargs E)

 
{

Thread =NewThread (NewThreadstart (dosomething ));

 
Thread. isbackground =True;

 
Thread. Start ();

 
}

 
}

However, consider thatProgramMore than the sub-thread will call the dosomething () method. Maybe the main thread or other modules call this method in multiple places. The most beautiful change is as follows:

 
Public Partial ClassTestthread: Form

 
{

Delegate VoidChangetextboxvalue (StringStr );

 
 

 
PublicTestthread ()

 
{

 
Initializecomponent ();

 
}

 
 

 
Thread thread;

 
 

 
VoidSettext (StringStr)

{

 
If(This. Invokerequired)// Obtain a value indicating whether the call comes from a non-UI thread

 
{

 
This. Invoke (NewChangetextboxvalue (settext), STR );

 
}

 
Else

 
{

 
This. Textbox1.text = STR;

 
}

 
}

 
 

 
VoidDosomething ()

 
{

 
// Do ......

 
Settext ("Abcdefg");

 
}

 
 

 
Private VoidButtonx1_click (ObjectSender, eventargs E)

 
{

 
Thread =NewThread (NewThreadstart (dosomething ));

 
Thread. isbackground =True;

 
Thread. Start ();

 
}

 
}

This. Invoke (New changetextboxvalue (settext), STR) // execute the specified delegate with the specified parameter list on the thread that owns the control's basic window handle

This. begininvoke (New changetextboxvalue (settext), STR); // run the specified delegate asynchronously with the specified parameter on the thread where the basic handle of the control is created.

Whether synchronous or asynchronous, the single-step trace debugging code will find that these methods will still return to the UI thread for execution, where the proxy is passed.

These two methods put a message into the message queue of the UI thread. When the UI thread processes the message, it will execute the passed method in its own context, in other words, all the threads that use begininvoke and invoke call are executed in the main UI thread. Therefore, if these methods involve some static variables, do not consider locking.

Let's take a look at a piece of running will throwInvalidoperationexceptionAbnormal code segment:

 
Public Partial ClassTestthread: Form

 
{

 
PublicTestthread ()

 
{

 
Initializecomponent ();

 
}

 
 

 
Thread thread;

 
 

 
VoidSettext (StringStr)

 
{

 
This. Textbox1.text = STR;

 
}

 
 

 
VoidDosomething ()

 
{

 
// Do ......

Settext ("XXX");

 
}

 
 

 
Private VoidButtonx1_click (ObjectSender, eventargs E)

 
{

 
Thread =NewThread (NewThreadstart (dosomething ));

 
Thread. isbackground =True;

 
Thread. Start ();

 
}

 
}

In vs2005 or later versions, this error is thrown if you access the properties of a control not on the control creation thread (generally the main UI thread, the solution is to use the invoke and begininvoke provided by the control to send the call mails back to the UI thread, that is, to let the control attribute be modified and executed on the UI thread.

The following code is correctly called after modification:

The direct modification method is as follows:

 
Public Partial ClassTestthread: Form

 
{

 
Delegate VoidChangetextboxvalue (StringStr );// Add a delegate proxy

 
 

PublicTestthread ()

 
{

 
Initializecomponent ();

 
}

 
 

 
Thread thread;

 
 

 
VoidSettext (StringStr)

 
{

 
This. Textbox1.text = STR;

 
}

 
 

 
VoidDosomething ()

 
{

 
// Do ......

 
This. Begininvoke (NewChangetextboxvalue (settext ),"XXX");// This. Invoke call is also available.

 
}

 
 

 
Private VoidButtonx1_click (ObjectSender, eventargs E)

{

 
Thread =NewThread (NewThreadstart (dosomething ));

 
Thread. isbackground =True;

 
Thread. Start ();

 
}

 
}

However, consider that more than the child threads in the program may call the dosomething () method. Maybe the main thread or other modules call this method in multiple places. The most beautiful change is as follows:

 
Public Partial ClassTestthread: Form

 
{

Delegate VoidChangetextboxvalue (StringStr );

 
 

 
PublicTestthread ()

 
{

 
Initializecomponent ();

 
}

 
 

 
Thread thread;

 
 

 
VoidSettext (StringStr)

{

 
If(This. Invokerequired)// Obtain a value indicating whether the call comes from a non-UI thread

 
{

 
This. Invoke (NewChangetextboxvalue (settext), STR );

 
}

 
Else

 
{

 
This. Textbox1.text = STR;

 
}

 
}

 
 

 
VoidDosomething ()

 
{

 
// Do ......

 
Settext ("Abcdefg");

 
}

 
 

 
Private VoidButtonx1_click (ObjectSender, eventargs E)

 
{

 
Thread =NewThread (NewThreadstart (dosomething ));

 
Thread. isbackground =True;

 
Thread. Start ();

 
}

 
}

This. Invoke (New changetextboxvalue (settext), STR) // execute the specified delegate with the specified parameter list on the thread that owns the control's basic window handle

This. begininvoke (New changetextboxvalue (settext), STR); // run the specified delegate asynchronously with the specified parameter on the thread where the basic handle of the control is created.

Whether synchronous or asynchronous, the single-step trace debugging code will find that these methods will still return to the UI thread for execution, where the proxy is passed.

these two methods add a message to the Message Queue of the UI thread. When the UI thread processes the message, the passed method will be executed in the context. In other words, all the threads that use begininvoke and invoke to call are executed in the main UI thread. Therefore, if these methods involve some static variables, do not consider locking.

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.