首頁 > 軟體

C#程式設計報錯System.InvalidOperationException問題及解決

2022-05-20 13:00:06

C#報錯System.InvalidOperationException

問題場景

在C# Windows GUI程式設計中,從某個子執行緒去存取設計器中的某個控制元件,例如將某個按鈕禁用。這樣就會觸發該異常:

System.InvalidOperationException:"執行緒間操作無效: 從不是建立控制元件"btn_exp"的執行緒存取它。"

問題原因

在C# Windows GUI程式設計中有一個規則,就是隻能通過建立控制元件的執行緒來存取控制元件,否則就可能產生不可預料的結果。

解決方案

方案一,打破規則

在建構函式中加入以下語句:

Control.CheckForIllegalCrossThreadCalls = false;

將以上屬性設定為假則會取消對非法跨執行緒呼叫進行檢查,簡單粗暴但不保證不出錯。

方案二,利用委託(Delegate)

.net為我們提供了Invoke 方法與BeginInvoke方法去呼叫委託,它們的區別在於前者是執行緒阻塞的,後者是非同步的。

因此當委託是一個較為耗時的函數時,Invoke 方法就會導致執行緒阻塞,表現為使用者介面卡頓;而BeginInvoke方法則不會等待委託執行完畢。

雖然BeginInvoke方法不會導致執行緒阻塞,但可以使用EndInvoke方法或者其它類似WaitHandle機制等待非同步操作的完成。

BeginInvoke(new MethodInvoker(()=>
{
    btn_exp.Enabled = false;
}));

其中,MethodInvoker委託 與EventHandler 委託的區別在於前者是不帶引數的:

public delegate void MethodInvoker();
public delegate void EventHandler(object sender, EventArgs e);

c# WPF InvalidOperationException異常的幾種常見原因

什麼是InvalidOperationException

操作無效異常。當方法呼叫對物件的當前狀態無效時引發的異常。

繼承

詳細說明

如果呼叫方法失敗是由無效引數以外的其他原因導致的,則使用該異常。通常, 當物件的狀態不支援方法呼叫時, 將引發此異常。

例如, 以下方法或原因會引發異常nvalidOperationException:

  • IEnumerator.MoveNext如果在建立列舉元后修改集合的物件,。
  • ResourceSet.GetString如果在執行方法呼叫前關閉資源集,。
  • XContainer.Add如果要新增的物件將導致結構不正確的 XML 檔案,。
  • 嘗試從非主執行緒或 UI 執行緒的執行緒操作 UI 的方法。
  • 從非 UI 執行緒更新 UI 執行緒(跨UI執行緒呼叫,樓主就是因為這個原因,線上程裡呼叫的UI控制元件導致報錯!)
  • 在迴圈存取集合時更改集合
  • 對其物件無法進行比較的陣列或集合進行排序
  • 將為 null <T>轉換為其基礎型別
  • 對空集合呼叫 system.exception 方法
  • 對沒有一個元素的序列呼叫 SingleOrDefault 或可列舉的。
  • 動態跨應用程式域欄位存取

由於InvalidOperationException異常可以在多種情況下引發,因此讀取由message屬性返回的異常訊息非常重要。

HRESULT

InvalidOperationException使用 COR_E_INVALIDOPERATION 值為0x80131509 的 HRESULT。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com