Я прочитал много сообщений о нитях, статьях и т. Д. О привязке и сходстве потоков с элементами управления графическим интерфейсом. Есть сообщение, в котором люди не хотят использовать Dispatcher
.Почему я должен избегать использования диспетчера?
У меня также есть помощник по работе, который избегает использования Диспетчера в своем коде. Я спросил его по причине, но его ответ меня не удовлетворил. Он сказал, что ему не нравится такая «магия», скрытая в классе.
Ну, я поклонник следующего класса.
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));
}
}
Возьмите здесь вопрос. Есть ли причины, по которым некоторые люди не хотят использовать такой класс? Возможно, мне придется пересмотреть этот подход.
Вы должны признать, что есть одна странная вещь. Dispatcher.CheckAccess()
исключен из Intellisense. Из-за этого они немного страшны.
Привет
РЕДАКТИРОВАТЬ:
Хорошо, еще один пример. Рассмотрим сложный объект. Коллекция в качестве примера была, возможно, не лучшей идеей.
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's 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?
}
}
«(BTW, в случае RaisePropertyChanged вам не нужно ничего отправлять - привязка уже делает это для вас, вам нужно только отправлять изменения в коллекции)« Ну, если это правда, то что-то было изменено с .Net 3.5. Рассмотрим коллекцию, которая загружается в отдельный поток, а затем передается этим потоком в свойство в ViewModel. Я не думаю, что это возможно без
Dispatcher
илиBackGroundWorker
. – DHNЯ не понимаю, почему во время модульного теста есть недостатки. Не могли бы вы объяснить это больше, пожалуйста? – DHN
@DHN - Смотрите мое обновление для примера проблемы с модульными тестами. Что касается «Рассмотрим коллекцию, которая загружается в отдельный поток, а затем передается этим потоком в свойство в ViewModel», я прямо упоминал, что «вам нужно только отправлять изменения в коллекции», поэтому да, вам нужно использовать ' Dispatcher' для изменения коллекций, но не для обычных свойств (т. Е. Вам не нужно поднимать событие INotifyPropertyChanged.PropertyChanged в потоке пользовательского интерфейса, но вы должны поднять 'INotifyCollectionChanged.CollectionChanged' в потоке пользовательского интерфейса). –