C#-何时进行线程安全调用



我有一个大型项目,我正在用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语句似乎异常令人讨厌。

只有当您从UI线程外部(即从您派生的任何线程)访问winform组件时,才需要该代码。核心库中有一些组件生成线程,例如FileSystemWatcher。Winforms不仅仅自己生成线程,它只有UI线程。任何跨线程问题都是由于您编写的代码或使用的库而发生的。

只有当代码没有在GUI线程中运行时,才需要调用代码。

我无法控制由哪个线程执行哪段代码

是的,你可以。GUI线程中运行的代码没有什么不可预测的,您只需要了解规则是什么。

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

(还有其他方法可以在另一个线程中运行代码,但您应该注意使用多线程。)

最新更新