日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

浅述WinForm多线程编程与Control.Invoke的应用

發布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅述WinForm多线程编程与Control.Invoke的应用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在WinForm開發中,我們通常不希望當窗體上點了某個按鈕執行某個業務的時候,窗體就被卡死了,直到該業務執行完畢后才緩過來。一個最直接的方法便是使用多線程。多線程編程的方式在WinForm開發中必不可少。
本文介紹在WinForm開發中如何使用多線程,以及在線程中如何通過Control.Invoke方法返回窗體主線程執行相關操作。

-. WinForm多線程編程
1. new Thread()

新開一個線程,執行一個方法,沒有參數傳遞:
privatevoid DoWork() {
?Thread t =new Thread(new ThreadStart(this.DoSomething));
?t.Start();
?}

private void DoSomething() {
?MessageBox.Show("thread start");
?}

新開一個線程,執行一個方法,并傳遞參數:
privatevoid DoWork() {
?Thread t =new Thread(new ParameterizedThreadStart(this.DoSomething));
?t.Start("guozhijian");
?}

private void DoSomething(object o) {
?MessageBox.Show(o.ToString());
?}
參數定義為object類型。
2. ThreadPool
眾所周知,新開一個線程代價是很高昂的,如果我們每個操作都新開一個線程,那么太浪費了,于是,下面使用線程池。
無參數傳遞:
privatevoid DoWork(){
?ThreadPool.QueueUserWorkItem(new WaitCallback(this.DoSomething));
?}

private void DoSomething(object o) {
?MessageBox.Show("thread start");
?}
有參數傳遞:
privatevoid DoWork() {
?ThreadPool.QueueUserWorkItem(new WaitCallback(this.DoSomething),"guozhijian");
?}

private void DoSomething(object o) {
?MessageBox.Show(o.ToString());
?}
使用匿名方法更靈活:
privatevoid DoWork() {
string name = "guozhijian";
?ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object o){
?MessageBox.Show(name);
?}
));
?}
在匿名代碼段里面可以直接訪問局部變量,不用在關心參數傳遞的問題
二. Invoke
1. this.Invoke
現在,在業務線程里面執行完畢,要改變窗體控件的值了,此時,如果直接通過this得到控件的句柄,然后對它進行操作是會拋異常的,.Net WinForm Application里面是不允許這樣的操作的。這是,可以調用Invoke方法

2.Invoke方法簽名:
object Control.Invoke(Delegate Method)
object Control.Invoke(Delegate Method, params object[] args)

3.使用自定義委托 privatevoid DoWork() {
?WaitCallback wc =new WaitCallback(this.DoSomething);
?ThreadPool.QueueUserWorkItem(wc,"Guozhijian");
?}


private delegate void MyInvokeDelegate(string name);
private void DoSomething(object o) {
this.Invoke(new MyInvokeDelegate(this.ChangeText), o.ToString());
?}


private void ChangeText(string name) {
this.textBox1.Text = name;
?}
哦,太麻煩了,難道我每次都要定義一個委托啊,這樣可不行。

4.使用System.Action:
privatevoid DoWork() {
?WaitCallback wc =new WaitCallback(this.DoSomething);
?ThreadPool.QueueUserWorkItem(wc,"Guozhijian");
?}

private void DoSomething(object o) {
this.Invoke(new Action<string>(this.ChangeText), o.ToString());
?}


private void ChangeText(string name) {
this.textBox1.Text = name;
?}
本例傳遞一個參數,System.Action有很多個重載,可以無參數(非泛型),而最多可以有四個參數,同樣采用匿名方法,不使用泛型形式的System.Action,如下:
privatevoid DoWork() {
?WaitCallback wc =new WaitCallback(this.DoSomething);
?ThreadPool.QueueUserWorkItem(wc,"Guozhijian");
?}

private void DoSomething(object o) {
this.Invoke(new Action(delegate(){
this.textBox1.Text = o.ToString();
?}
));
?}

5.使用System.Func
如果Invoke調用主窗體操作之后,還希望在調用完得到一個返回值:
privatevoid DoWork() {
?WaitCallback wc =new WaitCallback(this.DoSomething);
?ThreadPool.QueueUserWorkItem(wc,"Guozhijian");
?}

private void DoSomething(object o) {
?System.Func<string,int> f = new Func<string, int>(this.GetId);
object result = this.Invoke(f,o.ToString());
?MessageBox.Show(result.ToString());
?}


private int GetId(string name) {
this.textBox1.Text = name;
if (name == "Guozhijian"){
return 999;
?}

else {
return 0;
?}

?}

result的值為 999。
System.Func同樣有很多泛形重載,這里不贅述。

6.關于Invoke的擁有者:Control

本文例中都是用this來引用,這里this替換為窗體任何一個控件的句柄都是OK的,因為Control.Invoke含義是將方法委托給擁有該Control的線程去執行。?

轉載:http://www.cnblogs.com/ghfsusan/archive/2011/12/28/2304310.html

轉載于:https://www.cnblogs.com/aiwz/p/6153924.html

總結

以上是生活随笔為你收集整理的浅述WinForm多线程编程与Control.Invoke的应用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。