我是一名新手程序员,所以我可能会在这里完全弄错,但这个问题让我更加困惑。
这实际上是this问题的后续行动。
接受的答案是,您必须调用InvokeRequired以避免一些开销,因为您可能已经在UI线程上运行。
理论上,我同意它可以节省一些时间。经过一些测试后,我发现使用Invoke所需的时间比正常调用操作大两倍(测试如设置标签文本n次,或在RichTextBox中放置一个非常非常大的字符串)。
但是!然后就是练习。
MSDN文档说:
此属性可用于确定是否必须调用invoke方法,如果您不知道哪个线程拥有控件,这可能很有用。
在大多数情况下,当您尝试从其他线程访问控件时执行。实际上,我能想到的唯一情况是,从一个可以被线程X调用的方法以及所有者线程访问控件时。这对我来说是一个非常不可能的情况。
即使你真的不知道哪个线程试图操纵控件,也有一个事实是UI线程不必经常更新。对于您的GUI,25-30 fps之间的任何内容都应该没问题。在UI控件中进行的大多数更改所花费的时间远远少于毫秒。
因此,如果我理解正确,那么您必须检查是否需要调用的唯一情况是,您不知道哪个线程正在访问控件,以及何时GUI更新需要超过40毫秒才能完成
然后我在this询问http://programmers.stackexchange.com问题的答案。其中表明,当您不需要时,您不应该忙于过早优化。特别是如果它牺牲了代码的可读性。
所以这让我想到了一个问题:当你知道一个不同的线程访问一个控件时,你不应该使用invoke吗?当你知道你的UI线程可以访问那个部分时,你应该只使用 代码和您发现它应该运行得更快,您应该检查是否需要调用?
PS:在校对我的问题之后,听起来真的像是在咆哮。但实际上我只是好奇为什么InvokeRequired似乎被许多比我更有经验的程序员所滥用。答案 0 :(得分:9)
你在这里脱离背景。第一个问题you linked链接了另一个问题,特别是关于编写线程安全方法来访问UI控件。
如果您不需要对UI控件进行线程安全访问,因为您知道不会从其他线程更新它,那么您当然不应该使用此技术。只需更新您的UI控件,而无需使用InvokeRequired
或Invoke
。
另一方面,如果调用总是来自UI线程以外的线程,只需使用Invoke
而不先检查InvokeRequired
。
这导致三个简单的规则:
InvokeRequired
或Invoke
Invoke
。Invoke
与InvokeRequired
结合使用。答案 1 :(得分:8)
在实践中,人们倾向于从外部线程和拥有线程调用相同的方法。通常的模式是方法本身确定线程是否是拥有线程。如果是,则执行后续代码。如果不是,这次方法使用Invoke
调用自己的自己。
这样做的一个好处是它使代码更紧凑,因为你有一个与操作相关的方法而不是两个。
另一个也许更重要的好处是它减少了引发跨线程异常的可能性。如果两种方法在任何时候都可用,并且两个线程都可以选择这两种方法中的任何一种,那么就有可能出现看似合法的方法调用异常。另一方面,如果只有一种方法可以适应这种情况,那么可以提供更安全的界面。