我有一个大型项目,我正在用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语句似乎特别令人讨厌。
答案 0 :(得分:1)
如果从UI线程外部访问winform组件(即来自您生成的任何线程),则只需要该代码。核心库中有一些组件产生线程,例如FileSystemWatcher
。 Winforms不只是自己生成线程,它只有UI线程。由于您编写的代码或您使用的库,会出现任何跨线程问题。
答案 1 :(得分:0)
只需在代码未在GUI线程中运行时调用代码。
我无法控制哪个代码执行哪个代码
是的,你可以。关于哪些代码在GUI线程中运行没有什么不可预测的,你只需要找出规则是什么。
代码中用尽GUI代码的唯一代码是作为异步回调运行的方法,例如计时器或异步Web请求。 (System.Windows.Forms.Timer
虽然在GUI线程中运行Tick
事件。)
(还有其他方法可以在另一个线程中运行代码,但是你会发现使用多线程。)