引言
在進行winform程序開發(fā)需要進行大量的數據的讀寫操作的時候,往往會需要一定的時間,然在這個時間段里面,界面ui得不到更新,導致在用戶看來界面處于假死的狀態(tài),造成了不好的用戶體驗。所以在大量數據操作的應用上,需要使用多線程來處理這種情況。在c#中使用多線程很方便只需要使用system.threading.thread的一個實例的start方法就行了,但是如何實現多線程之間的交互就不是那么簡單。本文實現了用子線程去處理數據,并實時更新主線程的ui狀態(tài)了。下面就開始一步步的去實現異步線程更新ui的demo程序吧。
應用背景
寫入一定量的數據到文本文件中,同時需要在主界面中反應出寫入數據的實時進度情況。要求:需要將寫入數據封裝成一個類。
實現過程
1、首先建立一個winform項目,在主窗體上拖入一個button,一個progressbar,一個lable。如下圖所示。
2、編寫一個處理數據的類(writedate),源代碼如下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public class datawrite { public delegate void updateui( int step); //聲明一個更新主線程的委托 public updateui updateuidelegate; public delegate void accomplishtask(); //聲明一個在完成任務時通知主線程的委托 public accomplishtask taskcallback; public void write( object linecount) { streamwriter writeio = new streamwriter( "text.txt" , false , encoding.getencoding( "gb2312" )); string head = "編號,省,市" ; writeio.write(head); for ( int i = 0; i < ( int )linecount; i++) { writeio.writeline(i.tostring() + ",湖南,衡陽" ); //寫入一條數據,調用更新主線程ui狀態(tài)的委托 updateuidelegate(1); } //任務完成時通知主線程作出相應的處理 taskcallback(); writeio.close(); } } |
3、主界面中的代碼如下:
首先要建立一個委托來實現非創(chuàng)建控件的線程更新控件。
1
|
delegate void asynupdateui( int step); |
然后編寫多線程去啟動寫入數據的方法以及回調的函數。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
private void btnwrite_click( object sender, eventargs e) { int taskcount = 10000; //任務量為10000 this .pgbwrite.maximum = taskcount; this .pgbwrite.value = 0; datawrite datawrite = new datawrite(); //實例化一個寫入數據的類 datawrite.updateuidelegate += updatauistatus; //綁定更新任務狀態(tài)的委托 datawrite.taskcallback += accomplish; //綁定完成任務要調用的委托 thread thread = new thread( new parameterizedthreadstart(datawrite.write)); thread.isbackground = true ; thread.start(taskcount); } //更新ui private void updatauistatus( int step) { if (invokerequired) { this .invoke( new asynupdateui( delegate ( int s) { this .pgbwrite.value += s; this .lblwritestatus.text = this .pgbwrite.value.tostring() + "/" + this .pgbwrite.maximum.tostring(); }), step); } else { this .pgbwrite.value += step; this .lblwritestatus.text = this .pgbwrite.value.tostring() + "/" + this .pgbwrite.maximum.tostring(); } } //完成任務時需要調用 private void accomplish() { //還可以進行其他的一些完任務完成之后的邏輯處理 messagebox.show( "任務完成" ); } |
效果如下:
總結
實現異步更新ui有很多種方法,但是我認為這種方式是比較靈活,能實時的獲取到任務進行的狀態(tài),并且對之進行相應的處理。這種模式還適用于使用多個線程同時寫入不同的數據到不同的文件中去。
源代碼下載地址:winform.rar
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/mingjiatang/p/5079632.html