Используйте BackgroundWorker -класс.Его использование очень простое и довольно часто используется для таких задач, как загрузка данных.В следующем примере показано его использование:
BackgroundWorker bgWorker = new BackgroundWorker() { WorkerReportsProgress=true};
bgWorker.DoWork += (s, e) => {
// Load here your data
// Use bgWorker.ReportProgress(); to report the current progress
};
bgWorker.ProgressChanged+=(s,e)=>{
// Here you will be informed about progress and here it is save to change/show progress.
// You can access from here savely a ProgressBars or another control.
};
bgWorker.RunWorkerCompleted += (s, e) => {
// Here you will be informed if the job is done.
// Use this event to unlock your gui
};
bgWorker.RunWorkerAsync();
Использование BackgroundWorker позволяет UI-потоку продолжать обработку, и, следовательно, приложение реагирует на загрузку.Но из-за этого вы также должны убедиться, что никакие действия не могут выполняться с использованием загруженных данных.Очень простое решение - установить для свойства IsEnabled-свойства основных элементов пользовательского интерфейса значение false, а в RunWorkerCompleted установить значение true.Приложив немного фантазии, вы можете улучшить это тупое поведение с помощью приятного пользовательского интерфейса (в зависимости от приложения).
Это хороший совет для выполнения длительных операций в отдельном потоке (BackgroundWorker).Есть одно предупреждение: не создавайте WPF-элементы в DoWork-событии.Это не будет сделано, потому что все производные типы DependencyObject должны быть созданы в том же потоке, в котором они используются.
Существуют другие решения для этого, например, создание непосредственно потока или с использованием асинхронного шаблона на основе событий, ноЯ рекомендую использовать BackgroundWorker для вашей задачи, потому что он обрабатывает для вас водопровод.В итоге результат тот же, но путь к нему гораздо проще.