2017-04-04 109 views
0

我有一個控制檯應用程序,它啓動另一個線程中的表單應用程序(來自另一個類)。從另一個線程訪問「RichTextBox」組件

但是,我不想在主線程中訪問我的主類中的richTextBox1組件,並且拋出一個錯誤,說我試圖從另一個線程訪問該組件。

我的代碼: (窗體應用程序)

public partial class ChatGui : Form 
{ 
    public static RichTextBox textBox; 
    public ChatGui() 
    { 
     InitializeComponent(); 
     richTextBox1.ReadOnly = true; 
     richTextBox1.BackColor = SystemColors.Window; 
    } 

    public void WriteLine(string line) 
    { 
     richTextBox1.Text += line+"\r\n"; 
    } 

    private void textBox1_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.KeyCode == Keys.Enter) 
     { 
      WriteLine("[You]: "+textBox1.Text); 
      NetworkManager.SendPacket("rchat_msg " + textBox1.Text.Replace(" ", "%20")); 
      textBox1.Text = ""; 
      e.Handled = true; 
     } 
    } 

    public void Exit() 
    { 
     Application.Exit(); 
    } 

    private void ChatGui_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     e.Cancel = true; 
    } 

} 

主控制檯應用程序

public static void StartRemoteChat() 
    { 
     RemoteChat = true; 
     Program.ChatGui = new ChatGui(); 
     new Thread(new ThreadStart(() => 
     { 
      Application.Run(Program.ChatGui); 
      while (RemoteChat) 
      { 
       // ... 
      } 
     })).Start(); 
    } 

所以,我怎樣才能從我的主線程訪問richTextBox1成分(我想改變一些變數的組件)沒有這個錯誤發生?

+1

在一個側面說明,'應用。 Run()'是一個**阻塞**調用。你的'while(RemoteChat)'循環將**不會**,直到聊天表單被關閉**! –

+0

@Idle_Mind哦,你是對的!謝謝 ! –

回答

3

控件由創建它的線程擁有。 在你的情況下,你開始的線程擁有這個表單,因爲它會繪製它,所以它將成爲你的表單UI線程。

但是,當您嘗試使用另一個線程對控件進行更改時,它會像您所說的那樣引發異常。 解決這個問題的方法是調用創建它來,讓你想這樣的變化線程:

richTextBox1.BeginInvoke(new Action(()=> 
{ 
// make changes to control here. 
})); 
-2

嘗試設置下列屬性。

RichTextBox.CheckForIllegalCrossThreadCalls=false; 

這可能會幫助你。

+2

[No!](http://stackoverflow.com/a/15516124/107625) –

0

一個可以幫助你的是「CheckForIllegalCrossThreadCalls = FALSE;」但在這裏使用(開頭):

public Form1() 
    { 
     InitializeComponent(); 
     CheckForIllegalCrossThreadCalls = false;    
    } 

建議是使用每個調用「RichTextBox1」的invoke方法。 此方法允許與其他線程創建的元素進行交互。 例如:

richTextBox1.Invoke(new Action(() => richTextBox1.Text = "hello word")); 

「CheckForIllegalCrossThreadCalls =假」是如果在複雜的程序使用具有足夠的危險的解決方案。 我希望我是有幫助的。