Я пытаюсь прочитать большое количество строк из базы данных небольшими «кусочками» или страницами и сообщить о ходе работы пользователю;т. е. если я загружаю 100 «чанков», то отчет о ходе выполнения каждого чанка загружается.
Я использую TPL в C # 4.0 для чтения этих чанков из базы данных, а затем передаю полный набор результатов другомуЗадача, которая может использовать его.Я чувствую, что TPL дает мне лучший контроль над отменой и передачей задач, чем BackgroundWorker и т. Д., Но, похоже, нет встроенного способа сообщить о ходе выполнения задачи.
Вотрешение, которое я реализовал, чтобы сообщать о прогрессе в индикатор выполнения WPF, и я хочу убедиться, что это уместно и что нет лучшего подхода, который я должен использовать.
Я начал с создания простого интерфейса для представленияизменение прогресса:
public interface INotifyProgressChanged
{
int Maximum { get; set; }
int Progress { get; set; }
bool IsIndeterminate { get; set; }
}
Эти свойства могут быть связаны с ProgressBar в представлении WPF, а интерфейс реализуется вспомогательной моделью представления, которая отвечает за инициирование загрузки данных и в конечном итоге сообщает об общем ходе (для этого примера):
public class ContactsViewModel : INotifyProgressChanged
{
private IContactRepository repository;
...
private void LoadContacts()
{
Task.Factory.StartNew(() => this.contactRepository.LoadWithProgress(this))
.ContinueWith(o => this.UseResult(o));
}
}
Вы заметите, что я передаю ViewModel методу репозитория как INotifyProgressChanged, и именно здесь я хочу убедиться, что я не делаю что-то не так.
Мой мыслительный процесс заключается в том, чтобы сообщать о прогрессеs, метод, фактически выполняющий работу (метод репозитория), нуждается в доступе к интерфейсу INotifyProgressChanged, чтобы сообщить о прогрессе, в конечном итоге обновляя представление.Вот быстрый взгляд на метод репозитория (сокращенно для этого примера):
public class ContactRepository : IContactRepository
{
...
public IEnumberable<Contact> LoadWithProgress(INotifyProgressChanged indicator)
{
var resultSet = new List<Contact>();
var query = ... // This is a LINQ to Entities query
// Set the maximum to the number of "pages" that will be iterated
indicator.Maximum = this.GetNumberOfPages(query.Count(), this.pageSize);
for (int i = 0; i < indicator.Maximum; i++)
{
resultSet.AddRange(query.Skip(i * this.pageSize).Take(this.pageSize));
indicator.Progress += 1; // As each "chunk" is loaded, progress is updated
}
// The complete list is returned after all "chunks" are loaded
return resultSet.AsReadOnly();
}
}
И именно так репозиторий в конечном итоге сообщает о прогрессе в View через ViewModel.Это правильный подход?Правильно ли я использую TPL, нарушаю ли основные правила и т. Д.?Это решение работает, о прогрессе сообщается, как и ожидалось, я просто хочу убедиться, что я не настраиваю себя на неудачу.