Tôi đã đọc nhiều bài viết, bài viết vv về ràng buộc và mối quan hệ luồng của các điều khiển GUI. Có một số bài đăng mà mọi người không muốn sử dụng số Dispatcher
.Tại sao tôi nên tránh sử dụng Dispatcher?
Tôi cũng có một người bạn làm việc tránh sử dụng Dispatcher trong mã của mình. Tôi hỏi anh ta vì lý do này nhưng câu trả lời của anh ấy không thỏa mãn tôi. Anh ta nói, anh ta không thích loại ma thuật như vậy ẩn trong lớp.
Vâng, tôi là người hâm mộ của lớp học sau.
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));
}
}
Đây là câu hỏi. Có lý do nào khiến một số người không muốn sử dụng một lớp học như vậy không? Có lẽ tôi phải xem xét lại cách tiếp cận này.
Bạn phải thừa nhận, có một điều lạ. Dispatcher.CheckAccess()
bị loại trừ khỏi Intellisense. Có lẽ họ là một chút đáng sợ do thực tế này.
Trân
EDIT:
Ok, một ví dụ khác. Hãy xem xét một đối tượng phức tạp. Bộ sưu tập làm ví dụ có lẽ không phải là ý tưởng hay nhất.
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, trong trường hợp RaisePropertyChanged bạn không phải gửi bất cứ điều gì - ràng buộc đã làm điều đó cho bạn; bạn chỉ phải gửi thay đổi cho bộ sưu tập)" Vâng, nếu điều này là đúng thì một cái gì đó đã được thay đổi kể từ. Net 3.5. Hãy xem xét một bộ sưu tập được tải trong một chủ đề tách biệt và sau đó chuyển qua chuỗi này đến một thuộc tính trong một ViewModel. Tôi không nghĩ điều đó có thể xảy ra nếu không có
Dispatcher
hoặcBackGroundWorker
. – DHNTôi không hiểu tại sao có nhược điểm trong khi kiểm tra đơn vị. Bạn có thể giải thích điều này một litte nhiều hơn, xin vui lòng? – DHN
@DHN - Xem bản cập nhật của tôi để biết ví dụ về sự cố với các bài kiểm tra đơn vị. Đối với "Xem xét một bộ sưu tập được tải trong một chủ đề tách biệt và sau đó chuyển qua chuỗi này đến một thuộc tính trong một ViewModel" Tôi đã đề cập một cách rõ ràng rằng "bạn chỉ phải gửi các thay đổi tới các bộ sưu tập", vì vậy, vâng, bạn cần sử dụng ' Dispatcher' để sửa đổi các bộ sưu tập, nhưng không phải là các thuộc tính thông thường (nghĩa là bạn không phải tăng sự kiện 'INotifyPropertyChanged.PropertyChanged 'trên chuỗi giao diện người dùng, nhưng bạn phải tăng' INotifyCollectionChanged.CollectionChanged' trên chuỗi giao diện người dùng). –