2015-06-12 35 views
-2

我有兩個類(Data_Reader和Display_Data)和一個GUI_Form。
我想要的是在GUI_Form上存在的文本框上顯示Data_Reader類的讀取數據,以便包裝它我編寫了Display_Data類。
但我得到了如下因素的異常:c#winforms跨線程來自Warraper的更新GUI

跨線程操作無效:控制「textBox1的」從比它是在

創建的線程以外的線程訪問的任何人都可以知道如何解決這個 ? 我只是想更新GUI窗體上的讀取數據值。

// Gui Form 
// ============ 
public partial class GUI_Form: Form 
{ 
} 
// ============== 
// Display Data Class 
// =========== 
public static class Display_Data 
{ 
    public delegate void MyDelegate(Label myControl, string myArg2); 
    public static void DelegateMethod(Label myControl, string myCaption) 
     { 
      myControl.Text = myCaption; 
     } 
} 

//========================= 
// Reader Class 
//========================= 
public void Data_Reader 
{ 
    string Data_Received_text="Test"; 
    private System.ComponentModel.ISynchronizeInvoke _syn; 
    Meter_Data_Class.packets_received_counter_status_display++; 
    //it will call the display_Data class delegate method to update textbox on gui 
    syn.BeginInvoke(new 
        Display_Data.MyDelegate(Display_Data.DelegateMethod),Data_Received_text); 

} 

回答

0

使用textBox1.BeginInvoke()來調用委託。

0

您不能直接從不是UI線程的線程使用UI控件的方法或屬性。 這就是你得到這個例外的原因。 爲了克服這個障礙,你需要從不同的線程中調用一個委託來爲你做UI改變。 Control類中的System.Windows.Forms名稱空間包含一個名爲InvokeRequired的屬性,它告訴您當前線程是否爲UI線程或其他線程。 如果是UI線程,則可以使用control的屬性和方法。 如果它不是UI線程,則必須調用delegate才能使用control的屬性和方法。這是基於現有的委託在您發佈代碼的簡單方法:

public static void DelegateMethod(Label myControl, string myCaption) 
    { 
    // Calling from another thread? -> Use delegate 
    if (myControl.InvokeRequired) { 
     MyDelegate d = new MyDelegate(DelegateMethod); 
     // Execute delegate in the UI thread, pass args as an array 
     this.Invoke(d, new object[] { 
      myControl, 
      myCaption 
     }); 
    // Same thread, assign string to the textbox 
    } else { 
     myControl.Text = myCaption; 
    } 
} 
+0

你能解釋一下這個嗎? –

+0

那麼,爲什麼當你甚至不知道你是否在同一個線程中時,你在函數的開頭設置'myControl'的Text屬性? –

+1

哎呀,謝謝你的發現。那是一個錯誤。我從vb.net中的其他人那裏複製了這個答案,並且它已經作爲多個複製粘貼操作中的剩餘部分離開了。無論如何,我已經編輯了我的答案,以刪除該部分。 –