C#編程報(bào)錯(cuò)System.InvalidOperationException問題及解決
C#報(bào)錯(cuò)System.InvalidOperationException
問題場(chǎng)景
在C# Windows GUI編程中,從某個(gè)子線程去訪問設(shè)計(jì)器中的某個(gè)控件,例如將某個(gè)按鈕禁用。這樣就會(huì)觸發(fā)該異常:
System.InvalidOperationException:"線程間操作無效: 從不是創(chuàng)建控件"btn_exp"的線程訪問它。"
問題原因
在C# Windows GUI編程中有一個(gè)規(guī)則,就是只能通過創(chuàng)建控件的線程來訪問控件,否則就可能產(chǎn)生不可預(yù)料的結(jié)果。
解決方案
方案一,打破規(guī)則
在構(gòu)造函數(shù)中加入以下語句:
Control.CheckForIllegalCrossThreadCalls = false;
將以上屬性設(shè)置為假則會(huì)取消對(duì)非法跨線程調(diào)用進(jìn)行檢查,簡(jiǎn)單粗暴但不保證不出錯(cuò)。
方案二,利用委托(Delegate)
.net為我們提供了Invoke 方法與BeginInvoke方法去調(diào)用委托,它們的區(qū)別在于前者是線程阻塞的,后者是異步的。
因此當(dāng)委托是一個(gè)較為耗時(shí)的函數(shù)時(shí),Invoke 方法就會(huì)導(dǎo)致線程阻塞,表現(xiàn)為用戶界面卡頓;而BeginInvoke方法則不會(huì)等待委托執(zhí)行完畢。
雖然BeginInvoke方法不會(huì)導(dǎo)致線程阻塞,但可以使用EndInvoke方法或者其它類似WaitHandle機(jī)制等待異步操作的完成。
BeginInvoke(new MethodInvoker(()=> { ? ? btn_exp.Enabled = false; }));
其中,MethodInvoker委托 與EventHandler 委托的區(qū)別在于前者是不帶參數(shù)的:
public delegate void MethodInvoker(); public delegate void EventHandler(object sender, EventArgs e);
c# WPF InvalidOperationException異常的幾種常見原因
什么是InvalidOperationException
操作無效異常。當(dāng)方法調(diào)用對(duì)對(duì)象的當(dāng)前狀態(tài)無效時(shí)引發(fā)的異常。
繼承
詳細(xì)說明
如果調(diào)用方法失敗是由無效參數(shù)以外的其他原因?qū)е碌?則使用該異常。通常, 當(dāng)對(duì)象的狀態(tài)不支持方法調(diào)用時(shí), 將引發(fā)此異常。
例如, 以下方法或原因會(huì)引發(fā)異常nvalidOperationException:
- IEnumerator.MoveNext如果在創(chuàng)建枚舉器后修改集合的對(duì)象,。
- ResourceSet.GetString如果在執(zhí)行方法調(diào)用前關(guān)閉資源集,。
- XContainer.Add如果要添加的對(duì)象將導(dǎo)致結(jié)構(gòu)不正確的 XML 文檔,。
- 嘗試從非主線程或 UI 線程的線程操作 UI 的方法。
- 從非 UI 線程更新 UI 線程(跨UI線程調(diào)用,樓主就是因?yàn)檫@個(gè)原因,在線程里調(diào)用的UI控件導(dǎo)致報(bào)錯(cuò)!)
- 在循環(huán)訪問集合時(shí)更改集合
- 對(duì)其對(duì)象無法進(jìn)行比較的數(shù)組或集合進(jìn)行排序
- 將為 null <T>轉(zhuǎn)換為其基礎(chǔ)類型
- 對(duì)空集合調(diào)用 system.exception 方法
- 對(duì)沒有一個(gè)元素的序列調(diào)用 SingleOrDefault 或可枚舉的。
- 動(dòng)態(tài)跨應(yīng)用程序域字段訪問
由于InvalidOperationException異??梢栽诙喾N情況下引發(fā),因此讀取由message屬性返回的異常消息非常重要。
HRESULT
InvalidOperationException使用 COR_E_INVALIDOPERATION 值為0x80131509 的 HRESULT。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
WPF實(shí)現(xiàn)PropertyGrid功能
這篇文章主要為大家詳細(xì)介紹了在WPF中如何借助WinForm的PropertyGrid實(shí)現(xiàn)屬性列表功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2024-11-11C# .net實(shí)現(xiàn)貨幣轉(zhuǎn)換示例
這篇文章主要介紹了C# .net實(shí)現(xiàn)貨幣轉(zhuǎn)換,其中包含了try catch、switch語句的運(yùn)用,對(duì)于C#初學(xué)者有一定的借鑒價(jià)值,需要的朋友可以參考下2014-08-08C#異常處理中try和catch語句及finally語句的用法示例
這篇文章主要介紹了C#異常處理中try和catch語句及finally語句的用法示例,finally語句的使用涉及到了C#的垃圾回收特性,需要的朋友可以參考下2016-02-02C#進(jìn)行PDF表單域的創(chuàng)建填寫與刪除操作
通常情況下,PDF文件是不可編輯的,但PDF表單提供了一些可編輯區(qū)域,允許用戶填寫和提交信息,本文主要介紹了如何使用C#實(shí)現(xiàn)PDF表單域的創(chuàng)建,填寫與刪除操作,感興趣的可以了解下2024-04-04Unity實(shí)現(xiàn)鼠標(biāo)或者手指點(diǎn)擊模型播放動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)鼠標(biāo)或者手指點(diǎn)擊模型播放動(dòng)畫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-01-01C#使用Newtonsoft.Json庫實(shí)現(xiàn)JSON數(shù)據(jù)中某個(gè)字段值的提取功能
在C#中,可以使用Newtonsoft.Json庫(也稱為Json.NET)來處理JSON數(shù)據(jù),下面將通過幾個(gè)示例來展示如何從JSON格式的文本中提取某個(gè)字段的值,并將其存儲(chǔ)到字符串、列表或其他泛型集合中,需要的朋友可以參考下2025-03-03C#通過標(biāo)簽軟件Bartender的ZPL命令打印條碼
這篇文章介紹了C#通過標(biāo)簽軟件Bartender的ZPL命令打印條碼,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-01-01超簡(jiǎn)單C#獲取帶漢字的字符串真實(shí)長度(單個(gè)英文長度為1,單個(gè)中文長度為2)
正常情況下,我們是直接去string的length的,但是漢字是有兩個(gè)字節(jié)的,所以直接用length是錯(cuò)的2018-03-03