是不是;不要盲目地使用InvokeRequired只是一种糟糕的做法

本文关键字:一种 盲目 InvokeRequired 是不是 | 更新日期: 2023-09-27 18:20:44

我是一个新手程序员,所以我在这里可能完全错了,但这个问题比它应该的更困扰我。

这其实是对这个问题的跟进。

接受的答案是,您必须调用InvokeRequired以避免一些开销,因为您可能已经在UI线程上操作了。

理论上,我同意这可以节省一些时间。经过一些测试,我发现使用Invoke所花费的时间大约是正常调用操作的两倍(比如设置标签的文本n次,或者在RichTextBox中放置一个非常非常大的字符串)。

但是然后就是练习。

MSDN文档中写道:

此属性可用于确定是否必须调用invoke方法,如果您不知道哪个线程拥有控件,则该方法非常有用。

在大多数情况下,您确实知道何时尝试从另一个线程访问控件。实际上,我能想到的唯一情况是,当从线程X和所有者线程都可以调用的方法访问控件时。对我来说,这是一个非常不可能的情况。

即使你真的不知道哪个线程试图操纵控件,UI线程也不必那么频繁地更新。任何介于25-30帧/秒之间的内容都应该适合您的GUI。并且在UI控件中进行的大多数更改所需的时间远小于毫秒。

因此,如果我理解正确的话,您必须检查是否需要调用的唯一情况是,当您不知道哪个线程正在访问控件,并且GUI更新需要超过40毫秒才能完成时。

这就是我问的这个问题的答案http://programmers.stackexchange.com.它指出,当你不需要的时候,你不应该忙于过早的优化。特别是如果它牺牲了代码的可读性。

因此,这就引出了我的问题:当你知道另一个线程访问控件时,你不应该只使用invoke吗?当你知道你的UI线程可以访问那段代码时,你应该只使用,并且你发现它应该运行得更快,你应该检查是否需要invoke吗?

附言:校对完我的问题后,听起来真的像是在咆哮。但实际上,我只是好奇为什么InvokeRequired似乎被比我更有经验的程序员过度使用了。

是不是;不要盲目地使用InvokeRequired只是一种糟糕的做法

您在这里断章取义。您链接的第一个问题链接了另一个问题,具体是关于编写线程安全方法来访问UI控件。

如果你不需要对UI控件进行线程安全访问,因为你知道你不会从另一个线程更新它,那么当然,你不应该使用这种技术。只需在不使用InvokeRequiredInvoke的情况下更新UI控件。

另一方面,如果调用将始终源自UI线程以外的线程,则只需使用Invoke,而无需首先检查InvokeRequired

这导致了三个简单的规则:

  1. 如果仅从UI线程更新控件,则既不使用InvokeRequired也不使用Invoke
  2. 如果仅从UI线程以外的线程更新控件,请仅使用Invoke
  3. 如果同时从UI线程和其他线程更新控件,请将InvokeInvokeRequired结合使用

在实践中,人们倾向于从外部线程和拥有线程调用相同的方法。通常的模式是,方法本身确定线程是否为拥有线程。如果是,则执行后续代码。如果不是,则该方法这次使用Invoke调用自己。

这样做的一个好处是它使代码更加紧凑,因为您有一个与操作相关的方法,而不是两个。

另一个可能更重要的好处是,它减少了引发跨线程异常的机会。如果两个方法在任何时候都可用,并且两个线程都可以选择其中的任何一个,那么看似合法的方法调用就有可能引发异常。另一方面,如果只有一种方法可以适应这种情况,它提供了一个更安全的界面