WPF DependencyObject calling thread exception

谁说我不能喝 提交于 2019-12-02 03:16:32

The way I access it is like this. It gets the UI Thread's Dispatcher

System.Windows.Application.Current.Dispatcher.Invoke(
  (Action)(() => 
  {
      //Access the UI from here 
  }));

The main thing to note here between what I have and what you have listed in the comments is that mine will work regardless if you're in the behind code, the view model, a service class, wherever. Not all items have a Dispatcher on them so this.Dispatcher doesn't always work.

You can wrap your call inside an Action() being called from Dispatcher like this:

this.Dispatcher.BeginInvoke(new Action(() =>
{
    // your code accessing UI elements here
}));

Even though this is a fairly old thread, I wanted to give a hint to anyone who ran into the same thing I did. This is an intentionally verbose description so the search engines can find it for the next guy/gal who hits this obscure behaviour.

After getting the SetValue/GetValue compile error described here, I needed to derive my VM from a DependencyObject.

I wanted to continue deriving my VM from our ViewModelBase, which was derived from our AbstractNotifyPropertyChanged class (can't derive from 2 full classes in C#, of course). Being the super smart guy I am, I figured I would add the DependencyObject derivation to my AbstractNotifyPropertyChanged class. I couldn't see any reason why this little change would have any detrimental effects. For many weeks, the application was running fine.

There is always a big hairy "however". During testing, it was discovered that one of my comboboxes crashed the entire application when an item was selected. This was due to an unhandled InvalidOperationException. "The calling thread cannot access this object because a different thread owns it." The only thing that made this combobox different was the fact that it used DependencyProperty for some values.

Four days of frustrating debugging led nowhere because none of my code was making the call. It was all coming from WPF, and blowing up when the call stack reached VerifyAccess in GetValue. Obviously when it is being called by the framework, attempting to call Invoke to cross threads was not going to happen? Where would you put the Invoke call?

Since normal debugging failed, I had to go about it the hard way. I retraced my checkin steps to find the last time the code worked. I already had the idea that it was somehow related to the DependencyProperty of the combobox, so seeing the code changes, my suspicions pointed to the DependencyObject derivation.

After some finagling of the code derivations to remove DependencyObject from the chain for all of my ViewModels (through ViewModelBase), and placing that derivation only in the exact locations that I needed it, The problem has been solved.

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