Привязка данных в WinForms, выполняющих асинхронный импорт данных - PullRequest
5 голосов
/ 25 февраля 2010

У меня есть сценарий, в котором у меня есть коллекция объектов, привязанных к сетке данных в winforms. Если пользователь перетаскивает элемент в сетку, мне нужно добавить строку-заполнитель в сетку и начать длительный процесс асинхронного импорта. Мне нужно сообщить о состоянии процесса асинхронного импорта обратно в пользовательский интерфейс, обновив строку в сетке и оставив пользовательский интерфейс реагировать, чтобы позволить пользователю редактировать другие строки.

Какая лучшая практика для этого?

Мое текущее решение: связывание поточно-ориентированной реализации BindingList с сеткой, заполненной объектами, которые отображаются в виде строк в сетке. Когда пользователь перетаскивает элемент в сетку, я создаю новый объект, содержащий разреженную информацию, полученную из отброшенного элемента, и добавляю его в BindingList, отключая редактирование этой строки. Затем я запускаю отдельный поток, чтобы выполнить импорт, передавая ему только что связанный объект, который я только что создал, для заполнения данными. Процесс импорта периодически устанавливает состояние объекта и запускает событие, на которое подписывается пользовательский интерфейс, сообщая ему обновить сетку, чтобы увидеть новые свойства объекта.

Должен ли я передавать тот же объект, который привязан к сетке, в поток процесса импорта для работы, или я должен создать копию и объединить изменения объекта в потоке пользовательского интерфейса с помощью BeginInvoke?

Есть проблемы или советы по поводу этой реализации?

Спасибо

Ответы [ 4 ]

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

ок ...

Я вижу, что поток событий выглядит примерно так:

  1. пользователь перетаскивает элемент в сетку
  2. Асинхронный процесс запущен
  3. Пользовательский интерфейс обновлен, чтобы показать «обработку»
  4. обработчик обратного вызова получает ответ асинхронного процесса
  5. асинхронный обратный вызов обновляет источник привязки
  6. асинхронный обратный вызов вызывает «привязку данных» в сетке, чтобы обновить представление, содержащее новые данные.

Я бы использовал поток, а не фонового работника, но я довольно уверенно работаю с потоками.

Фоновый рабочий упрощает многопоточность, поэтому я бы рекомендовал начать с него, если вы не уверены.

Таким образом, вы обновляете источник и пользовательский интерфейс вместе, и пользователь может продолжать использовать приложение во время обработки.

0 голосов
/ 04 мая 2010

Я думаю, что BackgroundWorker поможет вам в этой задаче (вы также можете использовать отдельный поток с правом вызова invoke () в потоке пользовательского интерфейса). Проблема заключается в обновлении пользовательского интерфейса, выполняемого всеми отдельными потоками. Вы знаете, все обновления пользовательского интерфейса должны быть в том же потоке, в котором родился пользовательский интерфейс, поэтому создание безопасной реализации BindingList с блокировкой и выполнение большого количества обновлений может привести к тому, что форма не будет отвечать. Если вы используете BackgroundWorker, попробуйте ограничить использование ReportProgress, если форма отстает от гораздо более безопасного способа улучшить функциональность, это использовать 2 сетки данных. Вы можете расположить их один за другим, как будто это всего лишь одна сетка.

Bye

0 голосов
/ 05 мая 2010

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

0 голосов
/ 25 марта 2010

Похоже, что фоновый отчет о ходе работы поможет вам выполнить операции импорта и создания пользовательского интерфейса. Вы должны прочитать об этом Фоновом рабочем классе на MSDN

...