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

时间:2014-10-14 11:14:58

标签: c# multithreading forms

在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

错误:

  

跨线程操作无效:Control' applicationLog'从创建它的线程以外的线程访问。

我需要做什么?

2 个答案:

答案 0 :(得分:2)

使用Control.Invoke

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

答案 1 :(得分:1)

您的代码的问题在于您尝试从工作线程设置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线程和工作线程附加文本,如果不需要,它将不使用Control.Invoke(例如,从UI线程调用此方法时)。

以下是从工作线程和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