When developing a window application, it is often necessary to show what steps have been performed on the interface, and for a simple example, create a WinForm program, petition a button and a label on the form, and click on the button to do 100 loops. Displays the current number of cycles in real time on the label. A simple way to do this is to use Application.doevents, the code is as follows:
private void btnTest_Click (object sender, EventArgs e) {for (int i = 0; i <; i++) { thread.sleep (100); C3/>label1. Text = i + "/100"; Application.doevents (); }}
If the above code is application.doevents (), then when the button is clicked, the program will get stuck until the loop is completed, which is intolerable when the loop is large enough. However, the small amount of data with application.doevents () is OK, the amount of data is large use of application.doevents () will bring performance problems. So Application.doevents () to use with caution, in the large amount of data can be used in multi-threaded solution. As follows:
private void btnTest_Click (object sender, EventArgs e) { thread thread = new Thread (new ThreadStart (DoWork)); Thread. Start ();} private void DoWork () {for (int i = 0; i <; i++) {thread.sleep) ; Label1. Text = i + "/100"; }}
Well? There's an exception, right, yes. After the above code runs, the "inter-threading operation is invalid: it is accessed from a thread that does not create the control" Label1 ". "Exception. About what causes, we can Google a bit. However, the above code seems to work correctly in Vs03. Change the code to the following so that it works:
private void btnTest_Click (object sender, EventArgs e) { thread thread = new Thread (new ThreadStart (DoWork)); Thread. Start ();} private void DoWork () {for (int i = 0; i <; i++) {thread.sleep) ; This. Invoke (New action<string> (this). Changelabel), i.tostring ());} } private void Changelabel (string i) { Label1. Text = i + "/100";}
If too much writing a Changelabel method trouble, can be written in the form of anonymous methods, as follows:
private void btnTest_Click (object sender, EventArgs e) { thread thread = new Thread (new ThreadStart (DoWork)); Thread. Start ();} private void DoWork () {for (int i = 0; i <; i++) {thread.sleep) ; This. Invoke (New Action (delegate () {Label1. text=i+ "/100";}));} }
The DoWork method can also be removed using an anonymous method:
private void btnTest_Click (object sender, EventArgs e) { thread thread = new Thread (new ThreadStart (delegate () { f) or (int i = 0; i < i++) {thread.sleep) ; This. Invoke (New Action (delegate () {Label1. Text = i + "/100"; })); } })); Thread. Start ();}
If you want to pass parameters to the DoWork method, then you cannot use the ThreadStart class, you should use the Parameterizedthreadstart class, as follows:
private void btnTest_Click (object sender, EventArgs e) { string name = "Oec2003"; Thread thread = new Thread (new Parameterizedthreadstart (DoWork)); Thread. Start (name);} private void DoWork (object name) {for (int i = 0; i <; i++) {thread.sleep) ; This. Invoke (New Action (delegate () {Label1. Text=name+ ":" + i+ "/100";}));} }
We can also use the thread pool to implement
private void btnTest_Click (object sender, EventArgs e) { ThreadPool.QueueUserWorkItem (new WaitCallback (DoWork));} private void DoWork (object o) {for (int i = 0; i <; i++) {thread.sleep) ; This. Invoke (New Action (delegate () {Label1. text=i+ "/100";}));} }
How to use anonymous methods:
private void btnTest_Click (object sender, EventArgs e) { ThreadPool.QueueUserWorkItem (new WaitCallback (Delegate ( Object o) {for (int i = 0; i < i++) {thread.sleep) ; This. Invoke (New Action (delegate () {Label1. Text = i + "/100"; })); } }));}
Usually do a few Windows applications, multi-threaded understanding is not particularly deep, there is nothing wrong in the place to everyone correct.
[Transfer from]http://www.cnblogs.com/oec2003/archive/2009/12/20/1628412.html
An example of multithreading (UI live Display)