Выполнение задачи в фоновом режиме в приложении 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)