Several issues of using multithreading to access controls in WinForm in C #

Source: Internet
Author: User

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 class Form1:form

{

Public Form1 ()

{

InitializeComponent ();

}

private void Form1_Load (object sender, EventArgs e)

{

Thread thread = new Thread (threadfuntion);

Thread. IsBackground = true;

Thread. Start ();

}

private void Threadfuntion ()

{

while (true)

{

This.textbox1.text=datetime.now.tostring ();

Thread.Sleep (1000);

}

}

}

Running this code, we will see the system throws an exception:cross-thread operation not Valid:control ' textBox1 ' accessed from a thread and other than the thread It was created on. This is because . NET 2.0 later strengthens the security mechanism and does not allow The properties of the control 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 void Form1_Load (object sender, EventArgs e)

{

Control.checkforillegalcrossthreadcalls = false;

Thread thread = new Thread (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. We look at the definition of this attribute of checkforillegalcrossthreadcalls and we will find it to be a static , This means that no matter where we modify this 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 class Form1:form

{

Private delegate void Flushclient ();

Agent

Public Form1 ()

{

InitializeComponent ();

}

private void Form1_Load (object sender, EventArgs e)

{

Thread thread = Newthread (Crossthreadflush);

Thread. Isbackground=true;

Thread. Start ();

}

private void Crossthreadflush ()

{

to bind a proxy to a method

Flushclient FC = new Flushclient (threadfuntion);

This. BeginInvoke (FC);// Invoke proxy

}

private void Threadfuntion ()

{

while (true)

{

This.textbox1.text=datetime.now.tostring ();

Thread.Sleep (1000);

}

}

}

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:

public partial class Form1:form

{

Private delegate void Flushclient ();// Agent

Public Form1 ()

{

InitializeComponent ();

}

private void Form1_Load (object sender, EventArgs e)

{

Thread thread = new Thread (Crossthreadflush);

Thread. IsBackground = true;

Thread. Start ();

}

private void Crossthreadflush ()

{

while (true)

{

Place sleep and infinite loops outside of the waiting async

Thread.Sleep (1000);

Threadfunction ();

}

}

private void Threadfunction ()

{

if (this.textBox1.InvokeRequired)// wait for asynchronous

{

Flushclient FC = new Flushclient (threadfunction);

This. Invoke (FC);// call Refresh method via proxy

}

Else

{

This.textBox1.Text = DateTime.Now.ToString ();

}

}

}

Running the above code, we can see that the problem has been solved, by waiting for the asynchronous, we will not always hold the main thread of control, so that can not occur in the case of cross-thread call exception to complete multi-threaded WinForm Multi-line program control.

Several issues of using multithreading to access controls in WinForm 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.