为什么在.net中使用Invoke on Controls?

时间:2012-10-16 12:46:43

标签: c# .net invoke

  

可能重复:
  Why .NET does not allow cross-thread operations?
  Why is only the UI thread allowed to modify the UI?

根据我的理解,.net引发非法交叉线程调用异常的原因是GUI可能显示不确定行为。

但是其他每个对象都不是这样吗?如果两个线程在同一个对象上工作,则根据代码,该对象可能处于不确定的情况。那么为什么控制元素存在这种异常呢?或者为什么这个例外对控制元素是独占的。

使用invoke如何帮助?它仍然是不确定的。

3 个答案:

答案 0 :(得分:4)

Invoke - 需要对其他线程进行控制,因为cross-thread calls to Controls are not allowed。有关为何存在此限制的更完整的讨论,您应该阅读该链接 - 我不打算在此处回答,只是 (但请确保此限制存在于很好的理由)。

调用Invoke可以帮助我们,因为它允许后台线程在UI线程上“做东西” - 它可以工作,因为它不会直接调用该方法,而是发送一个Windows message表示“当你有机会的时候运行这个”。 UI线程正在运行message pump,它会持续处理发送到该线程的所有消息 - 通常这些消息类似于"the user clicked on this button",在这种情况下,Windows Forms通过引发Click事件来处理此消息关于相关控制。在这种情况下,Windows窗体通过运行提供的委托来处理消息。

结果是在任何一个时间点(UI线程)只有1个线程正在修改/使用UI控件。

请注意,Invoke不会对代表运行的顺序做任何保证。如果两个代表从两个不同的线程(甚至同一个线程)中Invoked以正确的顺序执行它的重要性,那么这就是另一个问题。


旁白:我们谈论“UI线程”,因为大多数应用程序都有一个创建所有控件的线程,但实际上不同的控件可以创建线程 - 它是控件的线程在哪个进程上创建了消息。显然,为了正确处理这些消息,必须在该线程上运行消息泵。

答案 1 :(得分:2)

大多数类型实际上并不是线程安全的,但可以在多个线程中使用,只要一个线程一次使用它们。

UI控件并不完全相同:它们具有线程关联性 - 它们只能 在UI线程上安全使用。

部分原因是UI线程可能希望随时重绘它们,因此它们必须随时可用。结合它不想在等待锁定时延迟UI线程,并且将它与希望避免甚至无争议锁定的愿望相结合(如果你可以帮助它)(并且UI线程必须采取如果需要为每次访问执行此操作,请输出批次锁定,并且您将获得一个简化模型,只需说明所有访问必须位于UI线程上。我确信可能设计一个没有线程亲和力的UI框架,但让它执行并且行为可预测会很棘手。

答案 2 :(得分:0)

Invoke用于确保您在正确的线程上调用UI。但每个.net对象都需要这个。 UI可以在单个线程上运行(WPF和Winforms也是如此)。两个不同的线程可以访问同一个对象,只要它不在同一时间。如果发生这种情况,它会创建一个竞赛案例并可能以死锁结束