Выполнение задачи в фоновом режиме в приложении WPF
Пример
private void Start(object sender, RoutedEventArgs e)
{
int progress = 0;
for (;;)
{
System.Threading.Thread.Sleep(1);
progress++;
Logger.Info(progress);
}
}
Каков рекомендуемый подход (TAP или TPL или BackgroundWorker или Dispatcher или другие), если я хочу Start()
- не блокировать поток ui
- может предоставлять отчеты о ходе выполнения.
- можно отменить
- поддержка многопоточных и многоядерных
Ответы
Ответ 1
В.NET 4.5 (или.NET 4.0 + Microsoft.Bcl.Async) лучшим способом является использование API-интерфейса Task
-based и async/await
. Это позволяет использовать удобный (pseudo-) последовательный код обработки и имеет структурированную обработку исключений.
Пример:
private async void Start(object sender, RoutedEventArgs e)
{
try
{
await Task.Run(() =>
{
int progress = 0;
for (; ; )
{
System.Threading.Thread.Sleep(1);
progress++;
Logger.Info(progress);
}
});
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Больше чтения:
Как выполнить задание в фоновом режиме WPF, предоставив при этом отчет и разрешить отмену?
Асинхронизация в 4.5: Включение выполнения и отмены в асинхронных API.
Async и Await.
Async/Await FAQ.
Ответ 2
Лучший способ сделать это - использовать BackgroundWorker
.
Причина, по которой я указываю это, - это специально разработанная для обработки работы в фоновом режиме, оставляя поток пользовательского интерфейса доступным и отзывчивым. Он также имеет встроенные уведомления Progress
и поддерживает Cancellation
.
Я предлагаю посмотреть несколько примеров BackgroundWorker.
Теперь, когда вы начинаете искать фонового работника, есть одна точка Cancellation
, с которой вам придется углубиться. Установка свойства cancel фонового рабочего не отменяет фонового рабочего, это просто повышает флагов для вашего запущенного метода, чтобы взаимодействовать через равные промежутки времени и грациозно прекращать обработку.
Вот один из моих сообщений, которые когда-то говорили об отмене фонового рабочего fooobar.com/questions/492645/...
Наконец-то. Asyncronous не означает многоядерные или даже многопоточные. (WIKI)
Ответ 3
Вы можете выполнить операцию в отдельном потоке в WPF, используя класс BackgroundWorker.
проверьте этот пример Как использовать фоновый рабочий стол WPF
И читайте о классе на MSDN здесь
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx