What's wrong with calling Invoke, regardless of InvokeRequired?

那年仲夏 提交于 2019-12-17 18:00:55

问题


I've seen the common setup for cross threading access to a GUI control, such as discussed here: Shortest way to write a thread-safe access method to a windows forms control

All the web hits I found describe a similar thing.

However, why do we need to check InvokeRequired? Can't we just call Invoke directly?

I assume the answer is no, so my real question is 'why'?


回答1:


From non-UI threads we can't touch the UI - very bad things can happen, since controls have thread affinity. So from a non-UI thread we must (at a minumum) call Invoke or BeginInvoke.

For UI-threads, however - we don't want to call Invoke lots of time; the issue is that if you are already on the UI thread, it still has the unnecessary overhead of sending a message to the form's pump and processing it.

In reality, in most threading code you know you expect a specific method to be called on a non-UI thread, so in those cases, there is no additional overhead: just call Invoke.




回答2:


InvokeRequired basically tells you if you're executing on the right thread or not. If you're not on the correct thread, you need to marshal the task to the correct thread otherwise you don't. Hence the need for the check.




回答3:


The issue is that GUI controls have a requirement that only code executing on the same thread that was used to instantiate the GUI control can access the GUI control. The reasons behind this requirement are tied to the way that Windows is architected. Suffice to say, it would very difficult to change this.

The InvokeRequired checks the identity of the current executing thread against the identity of the instantiating thread. If they are the same, the code can freely interact with the control. If not, the code must marshal the data across from the current thread to the instantiating thread. This is a slow and costly process and is to be avoided if at all possible. Your code will work if you always invoke and it may be that you will not notice the performance hit, but this scenario is going to be increasingly common as multi-core systems come into use. It is best not to create code "knots" that have to be undone later.




回答4:


If you try to invoke before a window handle is created (for example, when calling form constructor), you will get an InvalidOperationException. So, generally InvokeRequired check is required.

See MSDN for details.




回答5:


One reason I can think of is performence. If most of the time the calling thread is the same as the creating thread then you'll have some unnessecry overhead.




回答6:


The Invoke is going to call the code through Delegate and not directly which would be costly.

Its cost effective to call Invoke only when it required. Hence, InvokeRequired is used to find out is the call being made from same thread or another thread?



来源:https://stackoverflow.com/questions/747210/whats-wrong-with-calling-invoke-regardless-of-invokerequired

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!