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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【转】“线程间操作无效: 从不是创建控件的线程访问它”

發布時間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】“线程间操作无效: 从不是创建控件的线程访问它” 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
經典解決“線程間操作無效: 從不是創建控件的線程訪問它”
在編程中經常會遇到在一個按鈕中執行復雜操作,并將復雜操作最后返回的值加入一個ListView或ComboBox中候選。這個時候程序會卡,當程序員將這些卡代碼放進線程(Thread)中后發現當對控件操作時出現“線程間操作無效: 從不是創建控件的線程訪問它”異常。
????????為什么.net不讓我們跨線程操作控件,這是有好處的。因為如果你的線程多了,那么當兩個線程同時嘗試將一個控件變為自己需要的狀態時,線程的死鎖就會發生。但是難道就是因為這個原因,我們就只能讓程序卡著么?當然不是,這里教大家兩個個解決方案:

(1)不使用委托:在構造函數或者窗體Load的代碼里添加下面一句:
Control.CheckForIllegalCrossThreadCalls = False
(2)委托方法的實現

delegate void SetTextCallback(string text);
event SetTextCallback SetTextEvent;????
//調用窗體中的函數用invoke傳遞參數
private void SetText(string text)
{
????if (this.txtShow.InvokeRequired)
{????????????????
????SetTextCallback d = new SetTextCallback(SetText);
????this.Invoke(d, new object[] { text });
}
else
{??????????????????????
????this.txtShow.Text += text+"\n";
}
}

SetTextEvent += new SetTextCallback(SetText);

SetText(str);

(3)

this.Invoke(new MethodInvoker(DisplayReceiveMessage));
private void DisplayReceiveMessage()
{txt_visble.Text = "hello world" }


以上出自:好記性不如爛博客


==================================================================================
以下詳解出自:
http://hi.baidu.com/jcserver/blog/item/b7e8da3e2f6f35f0828b13f1.html


在設計中為了讓界面與邏輯分離,我的做法是使用事件,界面只要響應事件來處理界面的顯示就行了。而事件在邏輯處理中可能由不同的線程引發,這些事件的響應方法在修改界面中的控件內容時便會引發一個異常。

這時就用到了Control.InvokeRequired 屬性 與Invoke方法。

MSDN中說:
獲取一個值,該值指示調用方在對控件進行方法調用時是否必須調用 Invoke 方法,因為調用方位于創建控件所在的線程以外的線程中。
如果控件的 Handle 是在與調用線程不同的線程上創建的(說明您必須通過 Invoke 方法對控件進行調用),則為 true;否則為 false。
Windows 窗體中的控件被綁定到特定的線程,不具備線程安全性。因此,如果從另一個線程調用控件的方法,那么必須使用控件的一個 Invoke 方法來將調用封送到適當的線程。該屬性可用于確定是否必須調用 Invoke 方法,當不知道什么線程擁有控件時這很有用。

下面來說下這個的用法(我的一般做法):
首先定義一個委托,與這個事件處理函數的簽名一樣委托,當然直接使用該事件的委托也是可以的,如:

private delegate void InvokeCallback(string msg);
然后就是判斷這個屬性的值來決定是否要調用Invoke函數:

void m_comm_MessageEvent(string msg)
{
?? if(txtMessage.InvokeRequired)
?? {
????InvokeCallback msgCallback = new InvokeCallback(m_comm_MessageEvent);
????txtMessage.Invoke(msgCallback, new object[] { msg });
?? }
?? else
?? {
????txtMessage.Text = msg;
?? }
}
說明:這個函數就是事件處理函數,txtMessage是一個文本框。
這樣就做到了窗體中控件的線程安全性。
轉自:http://www.juanlian15.cn/article.asp?id=64

轉載于:https://www.cnblogs.com/gebenhagen/archive/2011/05/16/2048103.html

總結

以上是生活随笔為你收集整理的【转】“线程间操作无效: 从不是创建控件的线程访问它”的全部內容,希望文章能夠幫你解決所遇到的問題。

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