2009-05-01 34 views
2

我有一些未解決的線程問題。這是我第一次這樣做。我知道如何使用一個線程寫入文本框,但我不知道如何使用其中的兩個來完成這項工作。任何人都知道我必須做什麼才能使用兩個線程寫入相同的文本框,但不是在同一時間。謝謝。使用兩個線程寫入文本框

+1

什麼語言? – Aziz 2009-05-01 18:30:52

+0

即時通訊使用C#來做到這一點 – Allek 2009-05-01 18:38:15

回答

3

這是一個使用兩個線程將隨機數寫入多行文本框的示例。正如Brandon和Jon B指出的那樣,您需要使用Invoke()將調用序列化到GUI線程。

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    Random m_random = new Random((int)DateTime.Now.Ticks); 
    ManualResetEvent m_stopThreadsEvent = new ManualResetEvent(false); 

    private void buttonStart_Click(object sender, EventArgs e) 
    { 
     Thread t1 = new Thread(new ThreadStart(ThreadOne)); 
     Thread t2 = new Thread(new ThreadStart(ThreadTwo)); 

     t1.Start(); 
     t2.Start(); 
    } 

    private void ThreadOne() 
    { 
     for(;;) 
     { 
      int n = m_random.Next(1000); 
      AppendText(String.Format("One: {0}\r\n", n)); 
      if(m_stopThreadsEvent.WaitOne(n)) 
      { 
       break; 
      } 
     } 
    } 

    private void ThreadTwo() 
    { 
     for(;;) 
     { 
      int n = m_random.Next(1000); 
      AppendText(String.Format("Two: {0}\r\n", n)); 
      if(m_stopThreadsEvent.WaitOne(n)) 
      { 
       break; 
      } 
     } 
    } 

    delegate void AppendTextDelegate(string text); 

    private void AppendText(string text) 
    { 
     if(textBoxLog.InvokeRequired) 
     { 
      textBoxLog.Invoke(new AppendTextDelegate(this.AppendText), new object[] { text }); 
     } 
     else 
     { 
      textBoxLog.Text = textBoxLog.Text += text; 
     } 
    } 

    private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     m_stopThreadsEvent.Set(); 
    } 
} 
0

最安全的方法是隻有1個線程能夠在文本框(或任何GUI對象)上工作,讓任何其他線程需要在文本框上執行操作,將他們的需求傳達給控制文本框。

所以你的問題變成了如何在線程之間進行通信,這將成爲語言/操作系統的特定,所以你需要提供更多的信息。

+0

我不知道這是你要求的。我需要這樣做:例如,我有2個線程和1個文本框來寫入,在線程啓動後,我檢查文本框文本長度,並在5秒後執行以檢查文本框是否空閒,如果是的話,我寫入它在隨機時間隨機數字,而1線程正在使用文本框,其他人應該做的第一個,並檢查如果文本框是免費的,如果不是,他應該睡一個隨機時間,然後再檢查一遍。 – Allek 2009-05-01 18:42:59

0

您只能從主線程訪問GUI組件。要從另一個線程寫入文本框,您需要使用BeginInvoke()

1

另一種選擇是使用線程回調方法。這是一個存在於主線程中的方法,但在創建新線程時,您會傳遞對此方法的句柄/引用。這允許第二個線程調用主線程上的方法,並且更新/檢查文本框的功能將位於那裏。

研究線程之間的傳遞委託。

1

您可以做的一個選擇是將消息推送到Queue對象上,並使用Windows窗體上的計時器從該隊列中讀取消息並寫入文本框。

爲了使所有事情都變得更好,並且可以在讀取和寫入Queue對象時鎖定Queue對象。

例如:

private Queue<string> messages = new Queue<string>(); 

    /// <summary> 
    /// Add Message To The Queue 
    /// </summary> 
    /// <param name="text"></param> 
    public void NewMessage(string text) 
    { 
     lock (messages) 
     { 
      messages.Enqueue(text); 
     } 
    } 

    private void tmr_Tick(object sender, EventArgs e) 
    { 
     if (messages.Count == 0) return; 
     lock (messages) 
     { 
      this.textBox.Text += Environment.NewLine + messages; 
     } 
    }