【问题标题】:Can I safely bind to data on multi-threaded applications?我可以安全地绑定到多线程应用程序上的数据吗?
【发布时间】:2011-02-21 21:37:46
【问题描述】:

我正在尝试解决一个经典问题 - 我有一个运行一些多线程应用程序 处理器密集型计算,带有 GUI 界面。

每当一个线程完成一项任务时,我想 更新表格的状态

任务ID |状态

我使用 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 之间的中介 这真的有必要吗?

【问题讨论】:

    标签: c# multithreading data-binding


    【解决方案1】:

    1 - 否。后台任务必须在更新数据绑定属性之前同步到 UI 线程。这可以通过使用预定到TaskScheduler.FromCurrentSynchronizationContextTask 来完成。

    如果您还没有使用 .NET 4.0(例如,Task 不可用),那么这取决于您的“任务”如何操作:具有“完成”概念的任务可以使用 BackgroundWorker ,无限期运行的任务可以使用SynchronizationContext.Post

    2 - PropertyChanged 被绑定用于更新其显示。不知道为什么它对你有用而不叫它......

    3 - BindingSource 提供各种功能;见What Is a BindingSource and Why Do I Need It?

    顺便说一句:欢迎您就 SO 提出多个问题。这道题真的应该是三道题。

    【讨论】:

    • 现在我更好地理解了问题 2 的答案:我曾经滚动查看所有正在运行的任务的状态,每次滚动时,视图都会失效并且状态会发生变化。当我不滚动时,没有任何改变谢谢!
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多