我正在使用MVVM方法编写WPF应用程序。在我的ViewModel中,我有一个ObservableCollection。我的应用程序需要定期检查新消息,如果有,则需要将它们添加到ObservableCollection中。
如果我尝试添加到DoWork中的ObservableCollection,由于线程同步问题,它不起作用。看起来在UI线程上实现这一点的最简单方法是执行ReportProgress()并从那里更新集合。
我的问题是:在哲学和技术上,从ReportProgress处理程序更新UI是否可行,即使“通过法律条文”我实际上并没有报告进度。
有更好的方法吗?
*编辑:代码使用Dispatcher Timer *
视图模型
class MyViewModel
{
public ObservableCollection<string> MyList { get; set; }
public MyViewModel()
{
MyList = new ObservableCollection<string>();
}
}
“teh codez” - 只是一个示例,而不是我的实际应用程序代码。
private void Window_Loaded(object sender, RoutedEventArgs e)
{
MyViewModel mvm = new MyViewModel();
this.DataContext = mvm;
DispatcherTimer mytimer = new DispatcherTimer();
mytimer.Interval = TimeSpan.FromSeconds(5.0);
mytimer.Tick += new EventHandler(mytimer_Tick);
mytimer.Start();
}
void mytimer_Tick(object sender, EventArgs e)
{
((DispatcherTimer)sender).Stop();
MyViewModel mvm = this.DataContext as MyViewModel;
mvm.MyList.Insert(0, DateTime.Now.ToLongTimeString());
((DispatcherTimer)sender).Start();
}
这看起来它能够很好地满足我的需要,并且不会给我额外的行李,我不打算使用(例如取消,工作完成等)。
答案 0 :(得分:1)
不确定。这就是EventArgs的UserState的设计目的。
BackgroundWorker的原因是简化多线程。否则,您必须执行类似Invoke(或BeginInvoke)的操作来处理BackgroundWorker正在使用的相同内容。
答案 1 :(得分:1)
我不会这样做
它“感觉”就像将来会引发问题的东西(也许当其他人试图在几年后添加功能时,也许当这些代码升级或移植到具有稍微不同的ReportProgress实现的环境时)。
我只想使用Dispatcher.BeginInvoke(我也尝试避免使用Invoke,因为它使一个线程等待另一个线程并降低了首先使用多线程的效率)。
但是,有些地方只使用ReportProgress是正确的选择,你需要自己决定什么是你的具体情况最好的东西(我最讨厌的是评估“最佳实践”或“架构”更多然后制作实际工作软件)
答案 2 :(得分:1)
如果您正在应用程序中实现轮询类型功能,那么使用以间隔触发而不是在BackgroundWorker内部不断循环的DispatcherTimer可能更有意义。
http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchertimer.aspx