How to update the UI control value in WinForm/Silverlight multi-thread programming, winformui

Source: Internet
Author: User

How to update the UI control value in WinForm/Silverlight multi-thread programming, winformui

In a single-threaded winfom program, it is easy to set the value of a control. this. TextBox1.value = "Hello World! "; This is done, but if you do this in a new thread, for example:

Private void btnSet_Click (object sender, EventArgs e)
{
Thread t = new Thread (new ParameterizedThreadStart (SetTextBoxValue ));
// Of course, you can also use an anonymous delegate to write Thread t = new Thread (SetTextBoxValue );
T. Start ("Hello World ");
}


Void SetTextBoxValue (object obj)
{
This. textBox1.Text = obj. ToString ();
}

During running, a heartless error is reported:
The Inter-thread operation is invalid: It is accessed by a thread that does not create the control "textBox1.

The reason is that the UI control in winform is NOT thread-safe. If you can change its value in any thread at will, you can create a thread and I will create a thread, everyone is scrambling to change the value of "TextBox1". If there is no order, the world will be messy...

Solution:
1. Control. checkforillegalcrossthreadcils = false;) -- valid only for Winform

Using System;
Using System. Threading;
Using System. Windows. Forms;

Namespace ThreadTest
{
Public partial class Form1: Form
{

Public Form1 ()
{
InitializeComponent ();
Control. checkforillegalcrossthreadcils = false; // This row is critical.
}


Private void btnSet_Click (object sender, EventArgs e)
{
Thread t = new Thread (new ParameterizedThreadStart (SetTextBoxValue ));
T. Start ("Hello World ");
}


Void SetTextBoxValue (object obj)
{
This. textBox1.Text = obj. ToString ();
}
}
}

Set Control. checkforillegalcrossthreadcils is false, which is equivalent to not detecting conflicts between threads and allowing various threads to be messed up at will. Of course, the final TextBox1 value is unpredictable, only days know, but this is also the most effort-saving method.

2. Use delegate call-the most common method (only valid for WinForm)

Using System;
Using System. Threading;
Using System. Windows. Forms;

Namespace ThreadTest
{
Public partial class Form1: Form
{
Delegate void D (object obj );

Public Form1 ()
{
InitializeComponent ();
}


Private void btnSet_Click (object sender, EventArgs e)
{
Thread t = new Thread (new ParameterizedThreadStart (SetTextBoxValue ));
T. Start ("Hello World ");
}


Void SetTextBoxValue (object obj)
{
If (textBox1.InvokeRequired)
{
D d = new D (DelegateSetValue );
TextBox1.Invoke (d, obj );

}
Else
{
This. textBox1.Text = obj. ToString ();
}
}


Void DelegateSetValue (object obj)
{
This. textBox1.Text = obj. ToString ();
}
}
}

3. Use SynchronizationContext context-the most mysterious method (Winform/Silverlight can be used)

The reason why it is mysterious is that the msdn official explanation of it is also unclear.

Using System;
Using System. Threading;
Using System. Windows. Forms;

Namespace ThreadTest
{
Public partial class Form1: Form
{
Public Form1 ()
{
InitializeComponent ();
}

Private void btnSet_Click (object sender, EventArgs e)
{
Thread t = new Thread (new ParameterizedThreadStart (Run ));
MyPram _ p = new MyPram () {context = SynchronizationContext. Current, parm = "Hello World "};
T. Start (_ p );
}

Void Run (object obj)
{
MyPram p = obj as MyPram;
P. context. Post (SetTextValue, p. parm );
}


Void SetTextValue (object obj)
{
This. textBox1.Text = obj. ToString ();
}
}


Public class MyPram
{
Public SynchronizationContext context {set; get ;}
Public object parm {set; get ;}
}
}

4. Use BackgroundWorker-the lazy method (applicable to Winform and Silverlight)

BackgroundWorker will open another background thread outside the main thread. We can put some processing in the background thread for processing. After completion, the background thread will pass the result to the main thread and end itself at the same time.

Using System;
Using System. ComponentModel;
Using System. Windows. Forms;

Namespace ThreadTest
{
Public partial class Form1: Form
{
Public Form1 ()
{
InitializeComponent ();
}

Private void btnSet_Click (object sender, EventArgs e)
{
// MessageBox. Show (Thread. CurrentThread. ManagedThreadId. ToString ());
Using (BackgroundWorker bw = new BackgroundWorker ())
{
Bw. RunWorkerCompleted + = new RunWorkerCompletedEventHandler (bw_RunWorkerCompleted );
Bw. DoWork + = new DoWorkEventHandler (bw_DoWork );
Bw. RunWorkerAsync ("Hello World ");
}
}

Void bw_DoWork (object sender, DoWorkEventArgs e)
{
// MessageBox. Show (Thread. CurrentThread. ManagedThreadId. ToString ());
E. result = e. argument; // here, the parameter is simply returned as the result. Of course, after complicated processing, return the desired result (the operation is completed on another thread)
}

Void bw_RunWorkerCompleted (object sender, RunWorkerCompletedEventArgs e)
{
// The background thread is completed and the main thread is returned, so you can directly use the UI control.
This. textBox1.Text = e. Result. ToString ();
// MessageBox. Show (Thread. CurrentThread. ManagedThreadId. ToString ());
}
}
}

5. Dispatcher. BeginInvoke -- the exclusive secret of Silverlight

Code using System. Threading;
Using System. Windows. Controls;
Using System. Windows. Input;

Namespace ThreadTest
{
Public partial class MainPage: UserControl
{
Public MainPage ()
{
InitializeComponent ();
}

Private void LayoutRoot_MouseLeftButtonDown (object sender, MouseButtonEventArgs e)
{
Thread t = new Thread (SetTextValue );
T. Start ("Hello World ");
}

Void SetTextValue (object text)
{
This. Dispatcher. BeginInvoke () => {this.txt. Text = text. ToString ();});
}
}
}
Related Article

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.