C# 使用两个线程写入文本框
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/812595/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Writing to a textBox using two threads
提问by Allek
I have some unsolved issue with threads. It's my first time doing it. I know how to use one thread to write in a textBox, but I have no idea how to use two of them to do the job. Anyone have a clue what do I have to do to be able to use two threads to write to the same textBox, but not in the same time. Thank you.
我有一些未解决的线程问题。这是我第一次这样做。我知道如何使用一个线程在 textBox 中写入,但我不知道如何使用其中的两个来完成这项工作。任何人都知道我必须做什么才能使用两个线程写入同一个文本框,但不能同时写入。谢谢你。
采纳答案by Jeff Youel
Here's an example that uses two threads to write random numbers to a multi-line text box. As Brandon and Jon B noted, you need to use Invoke() to serialize the calls to the GUI thread.
这是一个使用两个线程将随机数写入多行文本框的示例。正如 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();
}
}
回答by Allek
safest approach is to only have 1 thread be able to work on the text box (or any gui object), have any other threads that need to perform an action on the text box communicate their needs to the thread that controls the text box.
最安全的方法是只有 1 个线程能够处理文本框(或任何 gui 对象),让任何其他需要对文本框执行操作的线程将它们的需求传达给控制文本框的线程。
so your question becomes how to communicate between threads, this is going to be language/OS specific so you need to provide more information.
所以您的问题变成了如何在线程之间进行通信,这将是特定于语言/操作系统的,因此您需要提供更多信息。
回答by Brandon
This MSDN Articleexplains how to make thread safe calls to windows form controls.
这篇MSDN 文章解释了如何对 windows 窗体控件进行线程安全调用。
回答by Jon B
You can only access GUI components from the main thread. To write to a textbox from another thread, you need to use BeginInvoke().
您只能从主线程访问 GUI 组件。要从另一个线程写入文本框,您需要使用BeginInvoke()。
回答by Joe.Ingalls
Another option is to use a Thread Callback method. This is a method that exists on the main thread, but when creating a new thread you pass a handle/reference to this method. This allows the second thread to call the method on the main thread and the functionality to update/check the textbox would sit there.
另一种选择是使用线程回调方法。这是一个存在于主线程上的方法,但是在创建新线程时,您将一个句柄/引用传递给该方法。这允许第二个线程调用主线程上的方法,更新/检查文本框的功能将位于那里。
Look into passing delegates between threads.
查看在线程之间传递委托。
回答by JDunkerley
One option you could do, is push messages onto a Queue object and use a timer on the windows form to read messages from this queue and write to the textbox.
您可以做的一个选择是将消息推送到 Queue 对象上,并使用 Windows 窗体上的计时器从该队列中读取消息并写入文本框。
In order to make everything nice and threadsage you could lock the Queue object when reading and writing to it.
为了使一切都很好,线程数可以在读取和写入时锁定 Queue 对象。
For example:
例如:
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;
}
}