Tôi đang viết ứng dụng đồ chơi Windows Store App cho Windows 8. Nó chỉ có một trang xaml với TextBlock
. Các trang có MyTimer lớp như DataContext
:Cập nhật giao diện người dùng ứng dụng Windows Store
this.DataContext = new MyTimer();
MyTimer
thực hiện INotifyPropertyChanged
và cập nhật tài sản Time
được thực hiện với một bộ đếm thời gian:
public MyTimer(){
TimerElapsedHandler f = new TimerElapsedHandler(NotifyTimeChanged);
TimeSpan period = new TimeSpan(0, 0, 1);
ThreadPoolTimer.CreatePeriodicTimer(f, period);
}
với
private void NotifyTimeChanged(){
if (this.PropertyChanged != null){
this.PropertyChanged(this, new PropertyChangedEventArgs("Time"));
}
}
các TextBlock
có dữ liệu về Thời gian
<TextBlock Text="{Binding Time}" />
Khi tôi chạy các ứng dụng tôi có ngoại lệ sau đây:
System.Runtime.InteropServices.COMException was unhandled by user code
Với thông điệp
The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))
Vấn đề thực sự là tôi đang cập nhật các tài sản của MyTimer lớp, không phải là GUI, Tôi không thể tìm ra, nhưng tôi nghĩ rằng giải pháp nên sử dụng một cái gì đó như this one.
Cảm ơn rất nhiều. Điều này cho thấy tôi, tôi sẽ cần phải sử dụng SynchronizationContext mỗi khi tôi sử dụng một cuộc gọi không đồng bộ ... Tôi sẽ suy nghĩ về làm một cái gì đó như thế với từ khóa async quá. – Gabber
Vâng, nếu bạn đang sử dụng từ khóa chờ đợi của C# 4.5, bạn sẽ nhận được điều này theo mặc định. –
Cảm ơn bạn đã trả lời!Tôi chỉ muốn thêm một sidenote: nếu bạn muốn gọi lại trong bối cảnh UI, hãy chắc chắn rằng bạn nắm bắt 'SynchronizationContext' không sớm hơn UI đã được xây dựng (tôi sử dụng trình xử lý sự kiện' OnLaunched' để làm điều đó), nếu không ngữ cảnh bạn lấy sẽ không phân phát. Đọc thêm: http://www.codeproject.com/Articles/31971/Understanding-SynchronizationContext-Part-I – Lvsti