a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C# > 正文

C#實現窗體與子線程的交互的方法

2020-01-24 02:36:08
字體:
來源:轉載
供稿:網友

本文實例簡述了C#實現窗體與子線程間通訊的方法,對于C#初學者有一定的借鑒價值。具體方法如下:

一般來說窗體上的UI在默認情況下不允許使用子線程(或者其它非創建控件的UI線程)去控制(這在NET2.0以下是允許的,但是考慮到安全性等問題,從2.0開始就禁止使用這個功能,除非Form的CheckForIllegalCrossThreadCalls=true,不推薦這樣使用)。

那么如何實現C#窗體與子線程的交互呢?具體方法如下:

一、使用Invoke或者BeginInvoke方法:

用一個線程,里邊調用Invoke或者BeginInvoke方法即可:

public partial class Form1 : Form{public void Processing(int num){int answer = 2;Task t = new Task(() =>{for (int i = 3; i <= num; i++){answer *= i;}this.BeginInvoke(new MethodInvoker(() => { Thread.Sleep(3000); MessageBox.Show("Finished!") }));MessageBox.Show("OK");});t.Start();}public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){MessageBox.Show("First!");Processing(10);}}

這里值得注意:
1)BeginInvoke:這里的“異步”并不是針對UI線程,而是說當Control的BeginInvoke在某個子線程中調用時,子線程中BeginInvoke后面的代碼(彈出“Finished”框框)會先執行,然后等到BeginInvoke中的那個委托方法完全執行完畢之后Label才會被賦值。如果改成Invoke,那么“OK”永遠在Invoke的委托代碼徹底執行完畢之后才被執行。
所以BeginInvoke=Invoke(在UI主線程中,所以不建議在主線程中直接這樣調用)

二、線程同步SynchronizedContext:

public partial class Form1 : Form{public void Processing(int num,SynchronizationContext context){int answer = 2;Task t = new Task(() =>{for (int i = 3; i <= num; i++){answer *= i;}SynchronizationContext.SetSynchronizationContext(context);SynchronizationContext.Current.Post((obj) => { Thread.Sleep(3000); MessageBox.Show("Finished"); }, null);MessageBox.Show("Last");});t.Start();}public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){MessageBox.Show("First!");Processing(10,SynchronizationContext.Current);}}

和BeginInvoke、Invoke類似,需要注意:

1)SynchronizationContext:唯獨在UI窗體線程中會自動初始化(button1_Click事件中SynchronizationContext.Current為當前窗體),其它線程與線程要交互,必須通過new SynchronizationContext()實現)。
2)Post方法等同于BeginInvoke作用,Send等同于Invoke作用。

大家如果仔細實驗代碼,還會發現無論何種情況,彈出“Finished”框框總是界面“假死”3秒,是的,證明了以上4個方法都是在UI線程上執行的(只不過是同步或者異步向窗體消息泵發送信息而已)。所以應該“一次性地把數據在子線程中先全部處理干凈(在Invoke,BeginInvoke,Send或者Post前得出結果,寫代碼),然后一次性發送通知給窗體,更新界面即可)。

此外還需要注意:

任何委托(Delegate)也有BeginInvoke方法,它是真正的異步,一旦Invoke一定是開辟一個線程去執行的。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 亚洲欧美日韩精品久久亚洲区 | 美女被草视频网站 | 中文字幕综合在线 | 成人精品在线 | 噜噜噜天天躁狠狠躁夜夜精品 | 精品国产乱码久久久久久1区二区 | 黄色毛片网站在线观看 | 日本在线观看一区二区 | 久久久久99精品国产片 | 亚洲久视频 | 久久三区 | 成人在线日韩 | 国产精品久久久久久久裸模 | 91精品久久久久久久久久久久久久久 | av男人电影天堂 | 天天干夜夜爽 | 国产精品视频播放 | 欧美亚洲高清 | 国产精品二区三区 | 中文视频一区 | 99国产精品99久久久久久 | 在线一区二区三区 | 日韩四区 | 色视频网址| 中文字幕一区二区三区精彩视频 | av中文字幕网 | 日韩免费福利视频 | 一二三四区在线观看 | 成人黄色片在线观看 | 999国产一区二区三区四区 | 国产精品久久久久影院 | 国产精品日韩欧美一区二区 | 亚洲精品乱码久久久久久蜜桃不卡 | 欧洲一区二区三区免费视频 | 美女视频久久 | 欧美日本成人 | 国产日韩精品在线观看 | 国产高清第一页 | 国产精品永久免费 | 精品久久影院 | 日韩高清国产一区在线 |