我正试图解决一个经典问题 - 我有一个运行一些的多线程应用程序 处理器密集型计算,带有GUI界面。
每次其中一个线程完成任务时,我都愿意 更新表格上的状态
taskID |状态
我以下列方式使用DataGridView和BindingList:
BindingList<Task> tasks;
dataGridView.DataSource = tasks
public class Task : INotifyPropertyChanged
{
ID{get;}
Status{get;set;}
}
后台线程可以安全地更新任务的状态吗? 和更改将在GUI中以正确的顺序显示?
第二个问题: 我什么时候需要致电PropertyChanged? 我试着在没有通话的情况下跑步,似乎没有打扰......
第三个问题: 我在MSDN上看到dataGridView使用BindingSource 作为DataGridView.DataSource和BindingList之间的中介 这真的有必要吗?
答案 0 :(得分:5)
1 - 否。在更新数据绑定属性之前,后台任务必须与UI线程同步。这可以通过使用Task
预定TaskScheduler.FromCurrentSynchronizationContext
来完成。
如果你还没有使用.NET 4.0(例如,Task
不可用),那么它取决于你的“任务”如何运作:具有“完成”概念的任务可以使用{ {1}},无限期运行的任务可以使用BackgroundWorker
。
2 - 绑定使用SynchronizationContext.Post
来更新其显示。不确定为什么它在没有调用的情况下适合你...
3 - PropertyChanged
提供各种功能;见What Is a BindingSource and Why Do I Need It?
答案 1 :(得分:1)
如果您一次只运行一个后台任务,BackgroundWorker可以解决您的问题,您可以使用WorkCompleted事件来更新您的UI。否则,如果有多个线程正在使用Control.BeginInoke将解决您的更新UI问题,在WPF上它将是Dispatcher.BeginInvoke。
在您的属性集上调用propertyChanged。但是如果您使用集合作为BindingObject,我将使用ObservableCollection。