Я заметил в WPF, что при попытке обновить пользовательский интерфейс из фонового потока (я знаю, что вы не должны этого делать - просто поиграть с вещами), что иногда он генерирует исключение InvalidOperationException, а иногда простоничего не делает.Впервые я заметил это, когда неправильно пытался обновить пользовательский интерфейс из фонового потока, запущенного асинхронным вызовом WCF (используя Begin / End, а не модель событий, которая автоматически маршалирует в поток пользовательского интерфейса).
Например,скажем, у меня есть простая форма с кнопкой и флажком.Этот код будет генерировать исключение InvalidOperationException («Вызывающий поток не может получить доступ к этому объекту, потому что другой поток владеет им.») Каждый раз:
private void button1_Click(object sender, RoutedEventArgs e)
{
new Thread(() => checkBox1.IsChecked = true).Start();
}
Теперь, примите ту же форму и добавьте стандартную службу болотассылка на простой сервис WCF где-то.Затем попробуйте это:
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
}
Насколько я понимаю, вызов Dispatcher.VerifyAccess () в этом методе обратного вызова должен быть сгенерирован, как и при попытке что-либо манипулировать на checkBox1.Вместо этого ничего не происходит - флажок в пользовательском интерфейсе не становится установленным, и никакое исключение не выдается.Кто-нибудь знает, почему это так?