I’ve noticed in WPF that when trying to update the UI from a background thread (I know that you’re not supposed to do this – just playing around with things) that sometimes it throws an InvalidOperationException, and sometimes it just does nothing. I first noticed this when I was improperly trying to update the UI from a background thread started by an async WCF call (using Begin/End, not the eventing model that automatically marshals to the UI thread).
For example, let’s say I’ve got a simple form with a button and a checkbox. This code will throw an InvalidOperationException (“The calling thread cannot access this object because a different thread owns it.”) every time:
private void button1_Click(object sender, RoutedEventArgs e)
{
new Thread(() => checkBox1.IsChecked = true).Start();
}
Now, take the same form, and add a bog-standard service reference to a simple WCF service somewhere. Then try this:
private void button1_Click(object sender, RoutedEventArgs e)
{
var client = new MyServiceClient();
//Note the use of Begin/End as opposed to the eventing model - Callback
//will not be called on the UI thread, but a worker thread. I have
//verified this through the debugger thread list and by checking the
//result of Dispatcher.CheckAccess() in the callback.
client.BeginMyServiceMethod("MyArgument", Callback, null);
}
private void Callback(IAsyncResult result)
{
//If I call Dispatcher.CheckAccess() here, it returns false,
//but if I call Dispatcher.VerifyAccess() it does not throw!
checkBox1.IsChecked = true; // no exception, no effect
}
My understanding is that a call to Dispatcher.VerifyAccess() in that callback method should throw, as should trying to manipulate anything on checkBox1. Instead, nothing happens – the checkbox in the UI does not become checked, and no exception is thrown. Does anyone know why this is the case?
Is it possible that the Framework code that’s making the call to the callback method is swallowing exceptions? Put a
try/catchin the callback to see if exceptions are being thrown. If so, then you know that the Framework is swallowing exceptions.