C# - 何时进行线程安全呼叫

时间:2012-08-04 20:49:11

标签: c# winforms multithreading

我有一个大型项目,我正在用C#工作,这是一种我很陌生的语言。该项目严重依赖于GUI,并且显示了大量数据。最近,我们一直在以前从未遇到过的跨线程错误。发生这些错误很容易解决:

if (logListView.InvokeRequired)
{
      logListView.BeginInvoke(new MethodInvoker(
          () => logListView.Items[logListView.Items.Count - 1].EnsureVisible()));
}
else
{
      logListView.Items[logListView.Items.Count - 1].EnsureVisible();
}

我的问题是:每次访问Windows窗体对象时都需要应用该方法吗?有特殊情况吗?我没有使用多线程,所以据我所知,这些错误发生的地方是我无法控制的。例如。我无法控制哪个代码由哪个线程执行:C#正在自己完成所有这些(我不太了解该语言)。为修改GUI的每一行实现if语句似乎特别令人讨厌。

2 个答案:

答案 0 :(得分:1)

如果从UI线程外部访问winform组件(即来自您生成的任何线程),则只需要该代码。核心库中有一些组件产生线程,例如FileSystemWatcher。 Winforms不只是自己生成线程,它只有UI线程。由于您编写的代码或您使用的库,会出现任何跨线程问题。

答案 1 :(得分:0)

只需在代码未在GUI线程中运行时调用代码。

  

我无法控制哪个代码执行哪个代码

是的,你可以。关于哪些代码在GUI线程中运行没有什么不可预测的,你只需要找出规则是什么。

代码中用尽GUI代码的唯一代码是作为异步回调运行的方法,例如计时器或异步Web请求。 (System.Windows.Forms.Timer虽然在GUI线程中运行Tick事件。)

(还有其他方法可以在另一个线程中运行代码,但是你会发现使用多线程。)