我是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);
}
我该怎么办?
答案 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更新。