2012-08-04 39 views
0

我有一个大型项目,我正在使用C#编写,这是一种我很新的语言。该项目很大程度上依赖于GUI,并且显示了大量数据。最近,我们一直在以前从未遇到过的地方发生跨线程错误。他们在那里发生这些错误很容易解决:C# - 何时进行线程安全调用

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

事实上,您获得跨线程异常意味着某段代码是线程化的。找出它是什么,你应该控制。 – 2012-08-04 20:54:52

回答

1

如果您从UI线程之外(即从任何已生成的线程)访问winform组件,则只需要该代码。核心库中有一些组件产生线程,例如FileSystemWatcher。 Winforms不仅仅是自己产生线程,它只有UI线程。任何交叉线程问题都是由于您使用的代码或库所引起的。

+0

我不会自己创建任何线程。有什么地方可以阅读更多关于创建自己的线程的类/组件? – williamg 2012-08-04 20:55:32

+0

没有关于它的概要。你必须通过你的代码并确定产生线程的组件。让应用程序运行,并在发生异常时检查调用堆栈。检查你使用的任何第三方库的文档。此外,使用'ThreadPool'是线程。虽然你不是手工创建它们,但它正在产生线程。偶然,你是否在使用它? – Femaref 2012-08-04 20:59:15

+0

我想这应该是显而易见的。我正在从SerialPort读取数据,并且几乎一定使用线程。我孤立了这个问题,一切都很好。 – williamg 2012-08-11 19:12:42

0

当代码没有在GUI线程中运行时,您只需调用代码。被执行的代码块

我无法控制由哪个线程

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

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

(有在另一个线程中运行的代码的其他方式,但后来你会意识到使用多线程的。)