如何使用表单textBox使跨线程操作线程安全

本文关键字:线程 操作 安全 何使用 表单 textBox | 更新日期: 2023-09-27 18:26:30

在c#(Visual Studio Express 2013)中,以下代码创建了如下所述的错误:

public void AddToAppLog(string formatter, string loggerId, string logText)
{
  lock(this)
  {
    DateTime dateTime = DateTime.Now;
    string logEntry =   dateTime.Hour.ToString("00")
                      + ":"
                      + dateTime.Minute.ToString("00")
                      + ":"
                      + dateTime.Second.ToString("00")
                      + "."
                      + dateTime.Millisecond.ToString("000")
                      + " [" + loggerId.PadRight(18, '·') + "]" + "> " 
                      + formatter
                      + logText
                      + "'n";
    applicationLog.AppendText(logEntry);
  } // end of lock
} // end of member function:  AddToAppLog

错误:

跨线程操作无效:控件"applicationLog"是从创建它的线程以外的线程访问的。

我需要做什么?

如何使用表单textBox使跨线程操作线程安全

使用Control.Invoke:

applicationLog.Invoke((MethodInvoker)delegate()
    {
        applicationLog.AppendText(logEntry);
    });

代码的问题是,您试图从工作线程设置UI线程拥有的对象的属性,这会导致跨线程异常。

为了在工作线程和UI线程之间正确地进行通信,一种常见的模式是使用Control.Invoke机制。你需要这样的功能:

private void AppendToAppLog(string text)
{
    // InvokeRequired required compares the thread ID of the
    // calling thread to the thread ID of the creating thread.
    // If these threads are different, it returns true.
    if (applicationLog.InvokeRequired)
    {
        this.Invoke(new Action<string>(s => applicationLog.AppendText(s)), text);
    }
    else
    {
        applicationLog.AppendText(text);
    }
}

然后您可以调用这个函数,而不是示例代码中的AppendText方法。

AppendToAppLog(logEntry);

此代码确保您可以从UI线程和工作线程附加文本,并且如果不需要(例如,从UI线程调用此方法时),它不会使用Control.Invoke。

下面是一个同时从工作线程和UI线程调用方法的示例:

private void button1_Click(object sender, EventArgs e)
{
    ThreadPool.QueueUserWorkItem((o) => AddToAppLog("", "5215", "Append first"), null);
    Task.Factory.StartNew(() => AddToAppLog("", "5215", "Append second"));
    AddToAppLog("", "5215", "Append third");
}

以及由此产生的文本框值:

14:26:40.533 [5215··············]> Append third
14:26:40.534 [5215··············]> Append first
14:26:40.554 [5215··············]> Append second