Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用两个线程写入文本框_C#_.net_Multithreading_Textbox - Fatal编程技术网

C# 使用两个线程写入文本框

C# 使用两个线程写入文本框,c#,.net,multithreading,textbox,C#,.net,Multithreading,Textbox,我有一些未解决的线程问题。这是我第一次这样做。我知道如何使用一个线程在文本框中写入,但我不知道如何使用其中两个线程来完成这项工作。任何人都知道我必须做什么才能使用两个线程写入同一个文本框,但不能同时写入。谢谢。最安全的方法是只有一个线程能够处理文本框或任何gui对象,让需要在文本框上执行操作的任何其他线程将其需要传达给控制文本框的线程 因此,您的问题变成了如何在线程之间通信,这将是特定于语言/操作系统的,因此您需要提供更多信息。这说明了如何对windows窗体控件进行线程安全调用。您只能从主线程

我有一些未解决的线程问题。这是我第一次这样做。我知道如何使用一个线程在文本框中写入,但我不知道如何使用其中两个线程来完成这项工作。任何人都知道我必须做什么才能使用两个线程写入同一个文本框,但不能同时写入。谢谢。

最安全的方法是只有一个线程能够处理文本框或任何gui对象,让需要在文本框上执行操作的任何其他线程将其需要传达给控制文本框的线程


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

这说明了如何对windows窗体控件进行线程安全调用。

您只能从主线程访问GUI组件。要从另一个线程写入文本框,您需要使用。

下面是一个使用两个线程将随机数写入多行文本框的示例。正如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();
    }
}

另一个选项是使用线程回调方法。这是一个存在于主线程上的方法,但在创建新线程时,您会向该方法传递句柄/引用。这允许第二个线程调用主线程上的方法,更新/检查文本框的功能将位于那里


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

您可以做的一个选项是将消息推送到队列对象上,并使用windows窗体上的计时器从该队列读取消息并写入文本框

为了使一切都变得更美好,您可以在读取和写入队列对象时锁定它

例如:

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

我不知道这是否是你要求的。我需要这样做:例如,我有2个线程和1个文本框要写,线程开始后,我检查文本框文本长度,5秒后再做,检查文本框是否空闲,如果是,我在随机时间内写随机数,当1个线程使用文本框时,另一个线程应该作为第一个线程,检查文本框是否空闲,如果没有,他应该随机睡一段时间,然后再检查一遍。