我可以安全地绑定到多线程应用程序上的数据吗?

时间:2010-05-20 14:08:31

标签: c# multithreading data-binding

我正试图解决一个经典问题 - 我有一个运行一些的多线程应用程序 处理器密集型计算,带有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之间的中介 这真的有必要吗?

2 个答案:

答案 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?

顺便说一下:欢迎你在SO上提出一个以上的问题。这个问题应该是三个。

答案 1 :(得分:1)

如果您一次只运行一个后台任务,BackgroundWorker可以解决您的问题,您可以使用WorkCompleted事件来更新您的UI。否则,如果有多个线程正在使用Control.BeginInoke将解决您的更新UI问题,在WPF上它将是Dispatcher.BeginInvoke。

在您的属性集上调用propertyChanged。但是如果您使用集合作为BindingObject,我将使用ObservableCollection。

相关问题