Why don't WinForms/WPF controls use Invoke internally?
I understand why GUI controls have thread affinity.
But why don't the controls use the invoke internally in their methods and properties?
Now you have to do stuff like this just to update TextBox
value:
this.Invoke(new MethodInvok开发者_如何学运维er(delegate()
{
textBox.Text = "newValue";
}
While using just textBox.Text = "newValue";
would be enough to represent the same logic.
All that would have to be done is change textBox.Text
logic from this (pseudocode):
public string Text
{
set
{
if(!this.InvokeRequired)
// do the change logic
else
throw new BadThreadException();
}
}
To this:
public string Text
{
set
{
if(!this.InvokeRequired)
// do the change logic
else
this.Invoke(new MethodInvoker(delegate()
{
// do the change logic
}
}
}
The same goes for getters and methods.
I'm certainly not proposing to remove Invoke
/BeginInvoke
, I'm just asking why the controls don't do the necessary thread switch themselves instead of throwing exception.
I think this way API enforces developers to make explicit decision and avoid unintentional programming mistakes. Here are several problems that I could come up with right away:
1. Unintentional thread blocking. If you write to a property, calling thread will have to block until message is processed by UI thread. And if calling thread owns a resource that UI thread might want to acquire you'll get a deadlock which is hard to debug (Calling thread holds a resource, and wait until message is processed by UI thread; UI thread waits until the resource is released).
2. Unexpected surprises. If we would make write operations implicitly asynchronous we run into a situation where reader should never expect values to be always up to date.
3. Performance impact. If you write an intensive algorithm which uses UI dispatching implicitly, you end up with really poor performance and you are free to blame framework developers. After all you wrote sorting that should run in O(n), but for some reason it takes ages to complete.
Well, unless any of the desginers or implementers from the framework answers, this can only be speculated upon, but the most obvious though that springs to (at least my) mind is complexity. Adding the thread switching logic in all relevant places of all controls would lead to a huge increase in their complexity (just imagine all testing needed to verify the behavior everywhere). It would probably simply not be worth the effort, so that work is transferred to the users of the controls (us, that), that need to take this little extra tour in the cases where it is needed.
Agree with @Code Gray, Windows shall thrown a Cross Thread calls exception if a different thread updates a control . However you can make thread safe calls - http://msdn.microsoft.com/en-us/library/ms171728(v=VS.100).aspx
精彩评论