2010-11-23 87 views
1

我寫了擴展類,用於文本框控件。.net多線程

public static class Extensions 
    { 
    public static void AddMessage(this System.Windows.Forms.TextBox textbox,string message){ 
      textbox.AppendText(DateTime.Now.ToString() + " " + message + "\r\n"); 
    } 
} 

我的文本框控件,傳遞到通過構造函數中的 「核心」 級,從形式,如:

public static TextBox text; 
public Core(TextBox text) 
{ 
    Core.text = text; 
} 

這裏是事件:

...{ 
change.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange); 
}... 

回調:

public void OnDataChange(object subscriptionHandle, object requestHandle, Opc.Da.ItemValueResult[] values) 
    { 
     Send(values,configuration.service.adress); 
    } 

public static void Send(Opc.Da.ItemValueResult[] values,string addr) { 
    text.AddMessage("test"); //here comes exception 
} 

and the text.AddMessage(.. 。)我有:「Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessagingException」

編輯: 我覺得我的問題不是功能Add.Message,導致文本框來擴展已經與例外,就是即時通訊misssing?所以,我認爲我甚至無法從「發送」功能

編輯稱之爲「文」:除了「文本」從

change.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange); 
+0

請參閱http://stackoverflow.com/questions/661561/how-to-update-gui-from-another-thread-in-c – alxx 2010-11-23 07:26:49

回答

3

您不能訪問或比其他線程改變UI正在添加內容一個負責所討論的控制。

您可以使用Windows Forms的Control.Invoke/BeginInvoke或WPF/Silverlight的Dispatcher.BeginInvoke將代理調用編組到右側線程。另外,BackgroundWorker也可以讓你的生活更輕鬆。像其他人說你不能從一個比主機控制其他線程訪問任何UI控件

public static class Extensions 
{ 
    public static void AddMessage(this TextBox textbox, string message) { 
     Action action =() => { 
      textbox.AppendText(DateTime.Now.ToString() + " " + message + "\r\n"); 
     }; 
     textBox.BeginInvoke(action); 
    } 
} 
+0

text.Invoke(new MethodInvoker(()=> {text.AddMessage( 「測試」);}));這樣做嗎?它也沒有工作... – eba 2010-11-23 07:29:16

1
public static void AddMessage(this TextBox textbox, string message) 
{ 
    Action<string> del = 
     msg => textbox.AppendText(DateTime.Now.ToString() + " " + msg + "\r\n"); 
    if (textbox.InvokeRequired) 
    { 
     textyBox.Invoke(del, message);   
    } 
    else 
    { 
     del(message); 
    } 
} 
0

例如,您的擴展類可能被更改爲。您始終可以使用Control.Invoke方法將委託的執行編組到UI線程中。但是,這可能不是您的情況中最好的方法。通常最好讓UI線程輪詢由工作線程更新的共享數據結構。這個想法是,你將有System.Windows.Forms.Timer定期檢查Tick事件處理程序的數據結構。 Opc.Da.DataChangedEventHandler事件處理程序將只更新數據結構。這具有許多優點。

  • 它打破了用戶界面和工作線程Control.Invoke強加之間的緊耦合。
  • 它將UI線程更新的責任置於UI線程上,無論如何它應該屬於它。
  • UI線程可以決定更新應該發生的時間和頻率。
  • 不存在UI消息泵被超載的風險,這與工作線程啓動的封送處理技術的情況相同。
  • 工作線程在進行下一步之前(即在UI線程和工作線程上獲得更多的吞吐量),不必等待已執行更新的確認。

這種方法的一個問題是數據結構將只包含從OPC服務器接收到的最新值。如果您需要捕獲由於某種原因而發生更改,那麼您可以輕鬆地將它們加載到OnDatachange方法中的隊列中。 UI線程可以定期卸載隊列。