I was playing with Task.ConfigureAwait
in order to better understand what is going beyond the hood. So i got this strange behavior while combining some UI acces
This one got me scratching my head a bit, but finally found the trick.
The code of the setter of the Button.Text
property is:
set
{
if (value == null)
value = "";
if (value == this.Text)
return;
if (this.CacheTextInternal)
this.text = value;
this.WindowText = value;
this.OnTextChanged(EventArgs.Empty);
if (!this.IsMnemonicsListenerAxSourced)
return;
for (Control control = this; control != null; control = control.ParentInternal)
{
Control.ActiveXImpl activeXimpl = (Control.ActiveXImpl) control.Properties.GetObject(Control.PropActiveXImpl);
if (activeXimpl != null)
{
activeXimpl.UpdateAccelTable();
break;
}
}
}
The line throwing the exception is this.WindowText = value;
(because it internally tries to access the Handle
property of the button). The trick is that, right before, it sets the text
property in some kind of cache:
if (this.CacheTextInternal)
this.text = value;
I'll be honest, I have no clue how this cache works, or when it is activated or not (turns out, it seems to be activated in this precise case). But because of this, the text is set even though the exception was thrown.
On further iterations of the loop, nothing happens because the property has a special check to make sure you don't set the same text twice:
if (value == this.Text)
return;
If you change your loop to set a different text every time, then you'll see that the exception is thrown consistently at each iteration.