Как выполнить задачу на фоне wpf, когда вы можете предоставить отчет и разрешить аннулирование?

Я хочу выполнить долговременную задачу после нажатия кнопки wpf. Вот что я сделал.

private void Start(object sender, RoutedEventArgs e) { for (int i = 0; i < 10; i++) { Thread.Sleep(2000); // simulate task } } 

Проблема в том, что wpf gui не отвечает. Я также хотел бы разрешить отмену и отчет о прогрессе каждые 1 секунду. Я расширяю код, как показано ниже.

  DispatcherTimer dispatcherTimer = new DispatcherTimer(); // get progress every second private int progress = 0; // for progress reporting private bool isCancelled = false; // cancellation private void Start(object sender, RoutedEventArgs e) { InitializeTimer(); // initiallize interval timer Start(10); // execute task } private void InitializeTimer() { dispatcherTimer.Tick += dispatcherTimer_Tick; dispatcherTimer.Interval = new TimeSpan(0,0,1); dispatcherTimer.Start(); } private void dispatcherTimer_Tick(object sender, EventArgs e) { Logger.Info("Current loop progress " + progress); // report progress } private void Cancel(object sender, RoutedEventArgs e) // cancel button { isCancelled = true; } private int Start(int limit) { isCancelled = true; progress = 0; for (int i = 0; i < limit; i++) { Thread.Sleep(2000); // simulate task progress = i; // for progress report if (isCancelled) // cancellation { break; } } return limit; } 

Моя целевая платформа – .NET 4.5. Каков рекомендуемый способ сделать это?

Благодарю.

Я думал, что ответил на ваш вопрос. Если вам нужно больше кода примера о том, как это сделать, используя параллельную библиотеку задач, с CancellationTokenSource и IProgress , вот оно:

 Action _cancelWork; private async void StartButton_Click(object sender, RoutedEventArgs e) { this.StartButton.IsEnabled = false; this.StopButton.IsEnabled = true; try { var cancellationTokenSource = new CancellationTokenSource(); this._cancelWork = () => { this.StopButton.IsEnabled = false; cancellationTokenSource.Cancel(); }; var limit = 10; var progressReport = new Progress((i) => this.TextBox.Text = (100 * i / (limit-1)).ToString() + "%"); var token = cancellationTokenSource.Token; await Task.Run(() => DoWork(limit, token, progressReport), token); } catch (Exception ex) { MessageBox.Show(ex.Message); } this.StartButton.IsEnabled = true; this.StopButton.IsEnabled = false; this._cancelWork = null; } private void StopButton_Click(object sender, RoutedEventArgs e) { this._cancelWork?.Invoke(); } private int DoWork( int limit, CancellationToken token, IProgress progressReport) { var progress = 0; for (int i = 0; i < limit; i++) { progressReport.Report(progress++); Thread.Sleep(2000); // simulate a work item token.ThrowIfCancellationRequested(); } return limit; } 

BackgroundWorker – это то, что вы ищете вместо DispatcherTimer.

Он обеспечивает поддержку отмены (через WorkerSupportsCancellation ) и сообщает о прогрессе в streamе пользовательского интерфейса (через WorkerReportsProgress ).

См. Превосходную подробную статью здесь – Как использовать BackgroundWorker .

  • Динамическая компоновка WPF с элементами управления и сеткой
  • Принудительное рендеринг элемента управления WPF в памяти
  • В WPF, как я могу определить, является ли элемент управления видимым для пользователя?
  • Прокрутите список в WPF в определенную строку
  • Как получить TreeViewItem из элемента HierarchicalDataTemplate?
  • Поиск контроля в элементе управления WPF
  • Каков наилучший подход к печати / отчетности из WPF?
  • DataTrigger, где значение НЕ равно нулю?
  • Внедрить INotifyPropertyChanged в сгенерированные classы Entity Framework
  • Форматирование даты в WPat datagrid
  • Как я могу создать поле со списком WPF шириной самого широкого элемента в XAML?
  • Interesting Posts

    Можно ли разделить одну линию Ethernet, выходящую из моей стены, на несколько отдельных линий?

    Пользовательский агент IE10 заставляет ASP.Net не отправлять обратно Set-Cookie (IE10 не устанавливает cookies)

    Как отправлять и получать SMS-сообщения с данными

    C # – вывод изображения в выходной stream ответа, дающий ошибку GDI +

    Что эквивалентно корню в Windows 8.1 и как я могу открыть оболочку в этом контексте?

    Как выбрать папки, которые нужно игнорировать во время поиска?

    Команда FOR / DO дает сообщение «Было неожиданным в это время» при запуске из командной строки

    Существуют ли эффективные антибликовые экраны?

    Подключение к нескольким VPN?

    Как сделать таймер обратного отсчета в Android?

    Как регистрировать HttpRequest и HttpResponse в файле?

    Почему strchr принимает int для char, который будет найден?

    Разверните div с середины, а не сверху и слева, используя CSS

    Как найти широту и долготу от адреса?

    Конструктор типа int

    Давайте будем гением компьютера.