2014-01-17 34 views
0

我有一個WinForm屏幕,也是消息使用者(使用Rhino ESB)。如果我在收到消息時嘗試更新屏幕上的任何內容,則什麼都不會發生。調用Invoke會給我一個錯誤,說明句柄沒有被創建。雖然表單是絕對創建的,但我在表單上單擊按鈕時觸發了一條消息,後臺進程發回一條消息。這是我想要更新UI的返回消息。從犀牛服務總線消費者訪問WinForm UI

這不是一個複雜的問題,沒有建議的解決方案工作。

我相信這裏的區別可能是因爲我在使用犀牛服務總線。犀牛可能會構建我的表單的一個單獨實例,而不是我正在使用的實例。我認爲我可能需要做的是讓Rhino通過將我的實例傳遞到Rhino使用的IoC容器中來將我的實例用作消費者。另一種選擇是將消費者轉移到自己的類別中,並將我的表單注入消費者,並在我的消費者表單上使用公共方法。這可能適用於我的應用程序,因爲這是主窗體,除非應用程序關閉,否則將永遠不會處理。這可能會在可能多次實例化的另一種形式上出現問題。也許我可以讓表單「觀察」另一個Consumer類更新的另一個靜態對象。請就最佳方法提出建議。

public partial class MainForm : Form, ConsumerOf<MoveJobCompletedEvent> 
{ 
    public void Consume(MoveJobCompletedEvent message) 
    { 
     // This does nothing! 
     txtLogs.Text = "\nJob completed!"; 
    } 
} 

這將引發一個錯誤:

 this.BeginInvoke((MethodInvoker)delegate 
     { 
      txtLogs.Text += "\nJob job completed!"; 
     }); 
ERROR: Invoke or BeginInvoke cannot be called on a control until the window handle has been created. 
+0

我讀過這些其他文章,但他們都沒有工作。這裏有些不同。 –

+0

使用該答案中提供的解決方案發布覆制,但不起作用。那可以解決你的問題。 –

+0

我相信不同的是RSB的使用。我認爲它可能會創建一個單獨的表單實例,這將解釋爲什麼它沒有完全初始化。編輯問題。 –

回答

0

看來你消耗JobCompleted事件創建窗口句柄之前。你可以試試以下內容:

public partial class MainForm : Form, ConsumerOf<MoveJobCompletedEvent> 
{ 
    public void Consume(MoveJobCompletedEvent message) 
    { 
     if (!this.HandleCreated) 
      return; 

     this.BeginInvoke((MethodInvoker)delegate 
     { 
      txtLogs.Text += "\nJob job completed!"; 
     }); 
    } 
} 
+0

如果我這樣做,它總是返回。爲什麼當我可以從窗體上的其他地方更新元素時​​,不會創建句柄(只是不在消費方法中)? –

+0

該句柄應該在窗口創建後幾毫秒內創建。所以,如果句柄還沒有被創建,你可以保護調用'BeginInvoke'。其他可能性是在創建'new MainForm()'後調用Control.CreateControl() –