2つのスレッドを使用してtextBoxに書き込む
-
03-07-2019 - |
質問
スレッドに関する未解決の問題があります。それをするのは初めてです。 1つのスレッドを使用してtextBoxに書き込む方法は知っていますが、2つのスレッドを使用してジョブを実行する方法はわかりません。 2つのスレッドを使用して同じtextBoxに書き込むことができるようにするには、何をする必要がありますか?ありがとう。
解決
2つのスレッドを使用して、複数行のテキストボックスに乱数を書き込む例を次に示します。 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();
}
}
他のヒント
別のオプションは、スレッドコールバックメソッドを使用することです。これはメインスレッドに存在するメソッドですが、新しいスレッドを作成するときに、このメソッドにハンドル/参照を渡します。これにより、2番目のスレッドがメインスレッドのメソッドを呼び出し、テキストボックスを更新/チェックする機能がそこに置かれます。
スレッド間でデリゲートを渡す方法を調べます。
できる方法の1つは、メッセージをQueueオブジェクトにプッシュし、windowsフォームのタイマーを使用してこのキューからメッセージを読み取り、テキストボックスに書き込むことです。
すべてを美しくし、スレッド化するために、読み取りおよび書き込み時に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;
}
}
最も安全なアプローチは、テキストボックス(または任意のguiオブジェクト)で作業できるスレッドを1つだけにし、テキストボックスでアクションを実行する必要がある他のスレッドに、テキストを制御するスレッドにニーズを伝えることです。ボックス。
あなたの質問はスレッド間での通信方法になります。これは言語/ OS固有のものになるため、詳細を提供する必要があります。
この MSDNの記事では、スレッドセーフな呼び出しを行う方法について説明しています。 Windowsフォームコントロール。
メインスレッドからのみGUIコンポーネントにアクセスできます。別のスレッドからテキストボックスに書き込むには、 BeginInvoke()。