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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

WinForm 之Control.Invoke 和Control.BeginInvoke 方法的使用 Control 不能在创建它的 Thread 之外被调用。但可以通过 invoke 来保证 C

發布時間:2023/12/18 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WinForm 之Control.Invoke 和Control.BeginInvoke 方法的使用 Control 不能在创建它的 Thread 之外被调用。但可以通过 invoke 来保证 C 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

WinForm 之Control.Invoke 和Control.BeginInvoke 方法的使用


Control 不能在創建它的 Thread 之外被調用。但可以通過 invoke 來保證 Control 線程安全。

在跨線程更新的時候,Control 會檢查 CurrentThread 是否為創建 Control 的線程,并報錯!

示例代碼如下:?

示例代碼 private?void?btnStart_Click(object?sender,?EventArgs?e)
{
?????
//注意:特地不使用?Timer?控件
?????Thread?thread?=?new?Thread(Fun);
?????thread.Start(DateTime.Now.ToString());
}

//報錯:線程間操作無效:?從不是創建控件“lblTime”的線程訪問它。
private?void?Fun(object?datetime)
{
?????lblTime.Text?
=?(string)datetime;
}


最簡單的解決方式是在程序代碼中添加如下屬性:

????????Control.CheckForIllegalCrossThreadCalls = false;


在多線程編程中,我們經常要在工作線程中去更新界面顯示,而在多線程中直接調用界面控件的方法是錯誤的做法,Invoke 和 BeginInvoke 就是為了解決這個問題而出現的,使你在多線程中安全的更新界面顯示。

將要做的事情放在工作線程中執行,而將對純粹的界面更新放到 UI 線程中去做,這樣也就達到了減輕 UI 線程負擔的目的。

?

使用?BeginInvoke?方法解決該問題的代碼如下:

使用BeginInvoke方法 using?System;
using?System.Collections.Generic;
using?System.ComponentModel;
using?System.Data;
using?System.Drawing;
using?System.Text;
using?System.Windows.Forms;
using?System.Threading;

namespace?Invoke_Test
{
????
public?partial?class?Form1?:?Form
????{

????????
//private?System.Windows.Forms.Label?lblTime;
????????
//private?System.Windows.Forms.Button?btnStart;

????????
public?Form1()
????????{
????????????InitializeComponent();
????????????
//?解決方式一
????????????
//?Control.CheckForIllegalCrossThreadCalls?=?false;
????????}

????????
private?void?btnStart_Click(object?sender,?EventArgs?e)
????????{
????????????
string?arg?=?DateTime.Now.ToString();

????????????
//?注意:創建子線程間接調用
????????????Thread?thread?=?new?Thread(FunStart);
????????????thread.Start(arg);?
//arg?給方法傳參??
????????}

????????
//?定義調用方法的委托
????????delegate?string?FunDelegate(string?str);

????????
//?注意:特地使用?FunStart?方法模擬間接調用
????????private?void?FunStart(object?obj)
????????{
????????????
//?要調用的方法的委托
????????????FunDelegate?funDelegate?=?new?FunDelegate(Fun);

????????????
/*========================================================
?????????????*?使用this.BeginInvoke方法
?????????????*?(也可以使用this.Invoke()方法)
????????????========================================================
*/

????????????
//?this.BeginInvoke(被調用的方法的委托,要傳遞的參數[Object數組])
????????????IAsyncResult?aResult?=?this.BeginInvoke(funDelegate,obj.ToString());

????????????
//?用于等待異步操作完成(-1表示無限期等待)
????????????aResult.AsyncWaitHandle.WaitOne(-1);

????????????
//?使用this.EndInvoke方法獲得返回值
????????????string?str?=?(string)this.EndInvoke(aResult);
????????????MessageBox.Show(str.ToString());
????????}

????????
//?真正需要執行的方法
????????private?string?Fun(string?datetime)
????????{
????????????lblTime.Text?
=?(string)datetime;
????????????
return?"委托的返回值";
????????}
????}
}


Control.InvokeRequired 屬性:當前線程不是創建控件的線程時為 true。
也可以認為,在 new Control() 的時候,Control 用一個變量記錄下了當前線程,在調用 InvokeRequired 時,返回當前線程是否不等于 new 的時候記錄下來的那個線程。

?

Control.Invoke 和 Control.BeginInvoke 就是“發短信”的方法,如果使用 Control.Invoke 發短信,那么甲線程就會像個癡情的漢子,一直等待著乙線程的回音,而如果使用 Control.BeginInvoke 發送短信,那發完短信后,甲線程就會忙活自己的,等乙線程處理完再來瞧瞧。


推薦閱讀:WinForm二三事(三)Control.Invoke&Control.BeginInvoke?

示例代碼Invoke_Test?

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的WinForm 之Control.Invoke 和Control.BeginInvoke 方法的使用 Control 不能在创建它的 Thread 之外被调用。但可以通过 invoke 来保证 C的全部內容,希望文章能夠幫你解決所遇到的問題。

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