Можно ли безопасно привязать данные к многопоточным приложениям? - PullRequest
1 голос
/ 20 мая 2010

Я пытаюсь решить классическую проблему - У меня есть многопоточное приложение, которое запускает некоторые ресурсоемкие вычисления с графическим интерфейсом.

Каждый раз, когда один из потоков завершил задачу, я бы хотел обновить статус на столе

taskID | статус

Я использую DataGridView и BindingList следующим образом:

BindingList<Task> tasks;
dataGridView.DataSource = tasks

public class Task : INotifyPropertyChanged
{
    ID{get;}
    Status{get;set;}
}

Может ли фоновый поток безопасно обновлять статус задачи? и изменения будут отображаться в правильном порядке в графическом интерфейсе?

Второй вопрос: Когда мне нужно позвонить в PropertyChanged? Я пытался бежать с вызовом и без него, похоже, не беспокоил ..

Третий вопрос: Я видел на MSDN, что dataGridView использует BindingSource в качестве посредника между DataGridView.DataSource и BindingList Это действительно необходимо?

Ответы [ 2 ]

5 голосов
/ 20 мая 2010

1 - Нет. Фоновые задачи должны синхронизироваться с потоком пользовательского интерфейса перед обновлением свойств базы данных. Это можно сделать с помощью Task, запланированного на TaskScheduler.FromCurrentSynchronizationContext.

Если вы еще не используете .NET 4.0 (например, Task недоступен), то это зависит от того, как работают ваши «задачи»: задача с концепцией «завершения» может использовать BackgroundWorker и задача, которая выполняется бесконечно долго, может использовать SynchronizationContext.Post.

2 - PropertyChanged используется привязкой для обновления своего отображения. Не уверен, почему это сработало для вас, не называя это ...

3 - BindingSource предоставляет различные функциональные возможности; см. Что такое BindingSource и зачем он мне нужен?

Кстати: вы можете задать несколько вопросов о SO. Этот один вопрос должен быть действительно три.

1 голос
/ 20 мая 2010

Если вы выполняете только одну фоновую задачу за раз, BackgroundWorker может решить вашу проблему, вы можете подписаться на событие WorkCompleted, чтобы обновить ваш пользовательский интерфейс. В противном случае, если существует несколько потоков, один из которых использует Control.BeginInoke, это решит проблему обновления пользовательского интерфейса, в WPF это будет Dispatcher.BeginInvoke.

PropertyChanged вызывается на множестве вашей собственности. Но если вы используете коллекцию в качестве BindingObject, я бы использовал ObservableCollection.

...