2014-02-18 3 views
0

У меня есть приложение Windows Forms, которое запускает процесс, который занимает до 3 часов. Пока он работает, я бы хотел, чтобы пользовательский интерфейс реагировал на команды «Остановить», а также обновлял ход выполнения задания. Говоря простыми словами, длительная работа вокруг цикла обрабатывает тысячи раз, обрабатывая записи, и именно в этом цикле я хотел бы обновить интерфейс.Запуск отдельного потока, обновление пользовательского интерфейса и возможность его отмены

Мне удалось запустить код, используя параметр FromCurrentSynchronizationContext с TPL Tasks. Я также использовал CancellationTokens, чтобы отменить текущий поток.

Однако я не могу понять, как совместить эти два.

+0

The BackgroundWorker разработан с учетом этого: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.110).aspx Пример выглядит практически так, как вы пытаетесь сделать , –

+1

Можете ли вы рассказать о том, что вы подразумеваете под * «объединить два» *? Если у вас есть токен отмены, вы просто передаете это с задачей и внутренне проверяете состояние. – James

+0

использовать BackgroundWorker. взгляните на его события и свойства, он может сообщить о прогрессе, который вы можете использовать для обновления прогресса в пользовательском интерфейсе. Он также поддерживает отмену. –

ответ

2

Не уверен, что вы подразумеваете под «объединить два» но здесь очень простой пример долго выполняющейся задачи с поддержкой отмены, который обновляет компонент пользовательского интерфейса после каждой итерации

var tokenSource = new CancellationTokenSource(); 
var token = tokenSource.Token; 

Task.Run(() => 
{ 
    for(int i = 0; i <= 50; i++) 
    { 
     Thread.Sleep(300); // simulate work 
     // check if the task has been cancelled and throw if required 
     if (token.IsCancellationRequested) 
      token.ThrowIfCancellationRequested(); 
     // otherwise update the UI 
     someTextBox.Invoke(() => someTextBox.Text = String.Format("Iteration: {0}", i)); 
    } 
} 
, token); 
// cancel the task after 5 seconds 
Task.Run(async delegate 
{ 
    await Task.Delay(5000); 
    tokenSource.Cancel(); 
}); 
+0

Task.Run Я считаю, что .Net 4.5, что бы эквивалент был в .Net 4.0. – user3324178

+0

@ user3324178 Task.Factory.StartNew – James

Смежные вопросы