使用两个线程写入textBox

时间:2021-05-28 21:01:32

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中写入,但我不知道如何使用其中两个来完成这项工作。任何人都知道我需要做什么才能使用两个线程写入同一个textBox,但不能同时写入。谢谢。

6 个解决方案

#1


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();
    }
}

#2


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.

另一种选择是使用Thread Callback方法。这是主线程上存在的方法,但在创建新线程时,您将传递对此方法的句柄/引用。这允许第二个线程在主线程上调用方法,并且更新/检查文本框的功能将位于那里。

Look into passing delegates between threads.

查看线程之间的传递委托。

#3


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;
        }
    }

#4


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.

所以你的问题变成了如何在线程之间进行通信,这将是语言/操作系统特定的,所以你需要提供更多的信息。

#5


This MSDN Article explains how to make thread safe calls to windows form controls.

这篇MSDN文章解释了如何对Windows窗体控件进行线程安全调用。

#6


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()。

#1


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();
    }
}

#2


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.

另一种选择是使用Thread Callback方法。这是主线程上存在的方法,但在创建新线程时,您将传递对此方法的句柄/引用。这允许第二个线程在主线程上调用方法,并且更新/检查文本框的功能将位于那里。

Look into passing delegates between threads.

查看线程之间的传递委托。

#3


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;
        }
    }

#4


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.

所以你的问题变成了如何在线程之间进行通信,这将是语言/操作系统特定的,所以你需要提供更多的信息。

#5


This MSDN Article explains how to make thread safe calls to windows form controls.

这篇MSDN文章解释了如何对Windows窗体控件进行线程安全调用。

#6


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()。