Calling Windows Forms controls across threads in C #

Source: Internet
Author: User


How do I invoke Windows Forms controls across threads in C #?

When we do WinForm applications, most of the time we run into the problem of using the control information on the interface with multithreading. However, we can not use the traditional method to do this problem, I will explain in detail below.
First look at the traditional approach:

       Public Partial classForm1:form { PublicForm1 () {InitializeComponent (); }         Private voidForm1_Load (Objectsender, EventArgs e) {Thread Thread=NewThread (threadfuntion); Thread. IsBackground=true; Thread.         Start (); }         Private voidthreadfuntion () { while(true)             {                  This. TextBox1.Text =DateTime.Now.ToString (); Thread.Sleep ( +); }         }     }

Run this code and we'll see that the system throws an exception:

' TextBox1 '  from a thread and other than the thread it is created on.

This is because. NET 2.0 strengthens security mechanisms and does not allow the control's properties to be accessed directly across threads in WinForm. So how to solve this problem, here are a few scenarios.
In the first scenario , we add a code to the Form1_Load () method:

      Private voidForm1_Load (Objectsender, EventArgs e) {Control.checkforillegalcrossthreadcalls=false; Thread Thread=NewThread (threadfuntion); Thread. IsBackground=true; Thread.         Start (); }

Add this code to find that the program can run normally. This code means that in this class we do not check whether a cross-thread invocation is legal (if there is no exception to this statement, then the system and the default are not checked). However, this method is not advisable. When we look at the definition of this attribute of Checkforillegalcrossthreadcalls, we find that it is static, which means that no matter where we modify the value in the project, he will work on the global. And like this cross-thread access is an exception, we usually check it out. If someone else in the project modifies this property, then our scenario fails and we have to take another approach.
The second scenario is to use delegate and invoke to control control information from other threads. There are a lot of people on the Internet to write this kind of control, but I read a lot of this kind of post, it seems that there is no problem, but in fact did not solve the problem, first of all, look at the network of the Imperfect way:

 Public Partial classForm1:form {Private Delegate voidFlushclient ();//Agent          PublicForm1 () {InitializeComponent (); }         Private voidForm1_Load (Objectsender, EventArgs e) {Thread Thread=NewThread (Crossthreadflush); Thread. IsBackground=true; Thread.         Start (); }         Private voidCrossthreadflush () {//to bind a proxy to a methodFlushclient FC =Newflushclient (threadfuntion);  This. BeginInvoke (FC);//Invoke proxy         }         Private voidthreadfuntion () { while(true)             {                  This. TextBox1.Text =DateTime.Now.ToString (); Thread.Sleep ( +); }         }     }

In this way we can see that the exception for cross-thread access is gone. But the new problem arises and the interface is not responding. Why this problem occurs, we just let the newly opened thread infinite loop refresh, theoretically should not have an impact on the main thread. In fact, this approach is actually equivalent to the new thread "injected" into the main control thread, it achieved the main thread control. As long as this thread does not return, the main thread will never respond. Even if the newly opened thread does not use an infinite loop, it can be returned. The use of multithreading in this way also loses its original meaning.
Now let's take a look at the recommended solution :

usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Windows.Forms;usingSystem.Threading; namespaceWindowsFormsApplication4 { Public Partial classForm1:form {Private Delegate voidFlushclient ();//AgentThread thread =NULL; intCounter =0;  PublicForm1 () {InitializeComponent (); }         Private voidButton1_Click (Objectsender, EventArgs e) {              This. ListBox1.Items.Clear (); Button1. Enabled=false; Thread=NewThread (Crossthreadflush); Thread. IsBackground=true; Thread.         Start (); }         Private voidButton2_Click (Objectsender, EventArgs e) {Thread.             Suspend (); Button1. Enabled=true; }         Private voidCrossthreadflush () { while(true)             {                 //Place sleep and infinite loops outside of the waiting asyncThread.Sleep ( +);             Threadfunction (); }         }         Private voidthreadfunction () {if( This. listbox1.invokerequired)//Waiting for asynchronous {flushclient FC=Newflushclient (threadfunction);  This. Invoke (FC);//calling the Refresh method through the proxy             }             Else{counter+=1;  This. Label1. Text =counter.                 ToString ();  This. LISTBOX1.ITEMS.ADD (System.DateTime.Now.ToString ()); }         }     } }

Calling Windows Forms controls across threads in C #

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.