2015-04-01 2 views
-2

Я хотел бы сделать следующее:Как выполнить фоновое задание без блокировки GUI, но передать обратно информацию в основной поток?

  • Есть кнопки и таблицу на GUI.
  • При нажатии на кнопку, задача запускается
  • Эта задача является цикл в то время, давая мне данные на каждой итерации

Как я могу запустить этот цикл и получить данные от каждой итерации этого в основной таблицы GUI, без блокировки GUI? Это важно, потому что условие останова снова является кнопкой в ​​графическом интерфейсе.

Я попытался использовать BackgroundWorker, но я действительно не могу понять, как отправлять данные на каждой итерации цикла (???). Я могу вернуть результат в конце, но это не цель. Если я запустил работника в цикле (но не имеет цикла в рабочем), он не работает.

private void ContinuousCoordinateAquisition(object sender, DoWorkEventArgs e) 
{ 
    while (continuousPositionAquisitionFlag == true)      // while the monitoring is not stopped, get positions 
    { 
     // get xyzwpr world coordinates 
     robotCoordinatesXYZWPRworld XYZWPRworld = robi.getRobotPosition_xyzwpr_world(); 

     Do something........... retuns values I need in GUI 

     // sleep for defined time 
     System.Threading.Thread.Sleep(1000); // wait 
    } 
} 

вызывающему будет

BackgroundWorker bw = new BackgroundWorker(); 
bw.DoWork += new DoWorkEventHandler(ContinuousCoordinateAquisition); 
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ContinuousCoordinateAquisitionCompleted); 

continuousPositionAquisitionFlag устанавливается из (кнопка стоп) кнопки. ContinuousCoordinateAquisitionCompleted здесь сделано только один раз, к сожалению, не каждая итерация.

+0

_Reactive Extensions_ ваш друг – MickyD

+0

Б имеют событие ProgressChanged, идеально подходят для отправка данных в основной поток. –

+0

Но когда вы делаете паузу в течение 1000 мс каждый цикл, вам может быть лучше с таймером. –

ответ

2

Вы на правильном пути. Вы должны использовать фоновый рабочий, но не ждите RunWorkerCompletedEventHandler, что происходит, когда все будет сделано.

Вместо этого внутри цикла периодически вызывается метод ReportProgress для рабочего фона. Это вызовет событие ProgressChanged, которое вы можете обрабатывать в своем потоке графического интерфейса.

Смотрите здесь: https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.progresschanged(v=vs.110).aspx

+0

Итак, я добавил: bw.ProgressChanged + = новый ProgressChangedEventHandler (ContinuousCoordinateAquisitionStep); и частная пустота ContinuousCoordinateAquisitionStep (объект отправитель, ProgressChangedEventArgs e) { e. ??? } Как я могу получить значения? e не имеет поля результата здесь ..... –

+0

Перед запуском работника вам необходимо установить для свойства WorkerReportsProgress значение True, https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker. workerreportsprogress (v = vs.110) .aspx. На вашем «Do somthing» вы должны вручную вызвать метод ReportProgress с параметром (параметр thare - это параметр userstate, то есть объект), который имеет данные, которые вы хотите передать. Это вызовет событие ProgressChanged. «e» также будет содержать ваш объект. См. Здесь: https://msdn.microsoft.com/en-us/library/a3zbdb1t(v=vs.110).aspx – Lucius

+0

Спасибо, что делает работу :) –

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