2011-12-22 93 views
0

我的應用程序中有一個異常處理項目,可以從任何地方調用以顯示用戶系統有問題。按照預期從UI中的某個地方撥打電話時,一切正常。當我從應用程序的任何UI部分撥打電話時,一切都會凍結。我將代碼包裝在線程安全調用中,並且在逐步執行時不需要調用Invoke。任何幫助是極大的讚賞。下面的代碼:從類線程安全調用窗體凍結應用程序

表單內

void err_DispEvent(string text) 
    { 
     if (InvokeRequired) 
     { 
      Invoke(new Error.DisplayDelegate(err_DispEvent), new object [] {text}); 
     } 
     else 
     { 
      this.Show(); 
     }   
    } 

呼叫

public void FaultError(string errorMsg) 
    { 
     FaultForm fform = new FaultForm(errorMsg, "Internal Fault"); 
     if (this.dispEvent != null) 
     { 
      dispEvent(errorMsg); 
     } 
    } 

    public event DisplayDelegate DispEvent 
    { 
     add { dispEvent += value; } 
     remove { dispEvent -= value; } 
    } 

    private event DisplayDelegate dispEvent; 

    public delegate void DisplayDelegate(string text); 

樣品的類是如何在應用程序中

ECDUExceptions.Error newError = ECDUExceptions.Error.getInstance(); 
newError.FaultError("Heater is not responding to function calls, it has been turned off"); 

回答

2

時重新調用方法的一些信息:

  1. 使用BeginInvoke(...),而不是Invoke(...),因爲這將不等待調用完成,因此不會凍結調用線程。

  2. 重新調用時使用Action。所以你的情況,你可以在你的調用更改爲:

    BeginInvoke(new Action<string>(err_DispEvent), text); 
    
+0

如果簽名匹配,是不是'BeginInvoke(err_DispEvent,text);'足夠? – Adam 2011-12-22 15:17:02

+0

@codesparkle我相信是這樣的,我寫了很多更清晰的內容。 – 2011-12-22 15:25:37

+0

你會介意,如果我建議編輯你的問題(顯示兩種選擇)? – Adam 2011-12-22 15:26:25

1

使用的BeginInvoke(使用.. )而不是Invoke(...)。這將把您的消息請求放在隊列末尾

0

爲應該顯示的消息創建某種排隊隊列。

從您需要的任何線程填充隊列。

從負責顯示消息的GUI中,使用計時器來出列並顯示它們。

簡單但不費吹灰之力。你不需要調用()任何東西,因爲Forms.Timer在UI消息循環上運行。

+0

這樣的隊列已經存在:消息循環。 使用BeginInvoke()在隊列末尾添加一個動作。 – Daniel 2011-12-22 15:46:44