Why should I avoid using a dispatcher?

I read a lot of thread posts, articles, etc. about the binding and similarity of threads with graphical user interface controls. There is a message in which people do not want to use Dispatcher .

I also have a helper who avoids using the Dispatcher in his code. I asked him for a reason, but his answer did not satisfy me. He said that he did not like the kind of β€œmagic” hidden in the classroom.

Well, I'm a fan of the next class.

 public class BindingBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private Dispatcher Dispatcher { #if SILVERLIGHT get { return Deployment.Current.Dispatcher; } #else get { return Application.Current.Dispatcher; } #endif } protected void RaisePropertyChanged<T>(Expression<Func<T>> expr) { var memberExpr = (MemberExpression)expr.Body; string property = memberExpr.Member.Name; var propertyChanged = PropertyChanged; if (propertyChanged == null) return; if (Dispatcher.CheckAccess()) propertyChanged.Invoke(this, new PropertyChangedEventArgs(property)); else Dispatcher.BeginInvoke(() => RaisePropertyChanged(expr)); } } 

That is the question. Are there reasons why some people do not want to use such a class? I may have to rethink this approach.

You have to admit that there is one strange thing. Dispatcher.CheckAccess() excluded from Intellisense. Perhaps because of this, they are a little scary.

Hi

EDIT:

Ok, another example. Consider a complex object. Perhaps the collection was not a good idea.

 public class ExampleVm : BindingBase { private BigFatObject _someData; public BigFatObject SomeData { get { return _someData; } set { _someData = value; RaisePropertyChanged(() => SomeData); } } public ExampleVm() { new Action(LoadSomeData).BeginInvoke(null, null); //I know - it quick and dirty } private void LoadSomeData() { // loading some data from somewhere ... // result is of type BigFatObject SomeData = result; // This would not work without the Dispatcher, would it? } } 
+7
source share
1 answer

I also personally do not mind Dispatcher in the model class. I have not seen any serious problems with this, but it gives maximum flexibility to your code.

But I like the idea of ​​using Dispatcher as much as possible in your infrastructure code. Just as you did with the RaisePropertyChanged method (BTW, in the case of RaisePropertyChanged you do not need to send anything - the binding already does this for you, you only need to send changes to the collection).

The biggest and only drawback that I see here is unit testing. When you try to test your logic, it may be difficult to use Dispatcher . Imagine if you had code like this in your view model:

 private void UpdateMyCollection() { IList<ModelData> dataItems = DataService.GetItems(); // Update data on UI Dispatcher.BeginInvoke(new Action(() => { foreach (ModelData dataItem in dataItems) { MyObservableCollection.Add(new DataItemViewModel(dataItem)); } })); } 

This type of code is pretty typical when it comes to updating collections from a thread other than the UI. Now, how would you write a unit test that checks the logic of adding items to an observable collection? First of all, you need to make fun of the Dispatcher property, because Application.Current is null during the execution of the unit test. Secondly, how do you mock this? Will you create a special thread that will simulate a user interface thread and use the Dispatcher this thread? So these are the things.

The bottom line is that if you want your code to be module-friendly, you need to think about how you will mock Dispatcher . This is the only problem.

Update:

The second example you provided will work without Dispatcher (binding will do the trick).

+5
source

All Articles