C#中的跨线程操作无效错误

时间:2012-08-20 02:48:11

标签: c# backgroundworker multithreading

我是C#和所有线程的新手,我现在得到“交叉线程操作无效错误”。

以下是代码的相关部分:

    private LinkedList<string> _statusList = new LinkedList<string>();

    private void ReportToStatus(string message)
    {
        _statusList.AddLast(message);\
        // textStatus is a textbox.
        // And this is the exact line that is giving the error:
        textStatus.Lines = _statusList.ToArray();
    }

    private void RunTest()
    {
        // ...

        // Run the test in the background worker.
        bgwTest.RunWorkerAsync(testCase);
    }

    private void bgwTest_DoWork(object sender, DoWorkEventArgs e)
    {
        TestCase testCase = e.Argument as TestCase;

        // ...

        // Run the test.
        switch (testCase.TestType)
        {
            case "TestA":    TestA(testCase);
                             break;
        }

        e.Result = testCase;
    }

    private void TestA(TestCase testCase)
    {
        // ...

            PrintStatistic(statisticsForCoil, testCase.OutputFile);
        }
    }

    private void PrintStatistic(int[] statistics, string outputFile)
    {
        // ...

        ReportToStatus(result);
    }

我该怎么办?

3 个答案:

答案 0 :(得分:1)

看起来_statusList中可能存在问题。你不能从另一个线程写入它,只能读取。

来自MSDN

  

“LinkedList类不支持链接,拆分,循环,   或其他可能使列表处于不一致状态的功能。   该列表在单个线程上保持一致。唯一的多线程   LinkedList支持的场景是多线程读取操作。“

此外,您无法从后台线程访问UI。您需要使用调度程序在UI线程上调用操作。为此,您的代码需要看起来像这样

<强> WPF

    Application.Current.Dispatcher.Invoke(new Action(delegate
                                   {
                                        textStatus.Lines = _statusList.ToArray();
                                   }));

<强>的WinForms

    textStatus.Invoke(new Action(delegate
                                   {
                                        textStatus.Lines = _statusList.ToArray();
                                   }));

答案 1 :(得分:1)

BackgroundWorker有一个更新UI的专用机制: BackgroundWorker.ReportProgress。例如,在您的代码中,它可能如下所示:

private void ReportToStatus(string message)
{
    _statusList.AddLast(message);
    // textStatus is a textbox.
    // And this is the exact line that is giving the error:
    bgwTest.ReportProgress(0, _statusList.ToArray());
}

//Assuming this is the method handling bgwTest's ProgressChanged event
private void bgwTest_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
     textStatus.Lines = (string[])(e.UserState);
}

答案 2 :(得分:0)

您正在尝试从后台工作程序更新UI,这将导致该异常。您可以使用Dispatcher来安排更新 - 或者更理想地使用后台工作程序来执行“后台”工作,然后在引发RunWorkerCompleted事件时进行UI更新。