2015-07-31 3 views
2

мой вопрос заключается в следующем:Пользовательский интерфейс работает на отдельной теме?

1.I имеют интенсивный метод, который обновляет графический элемент (диаграмма) в цикле в то время как

2.I нужно вырваться из этого цикла, когда нажата кнопка.

3.Проблема - обработчик событий кнопки не запускается до тех пор, пока цикл while не будет завершен.

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

Любая идея, как это можно сделать?

private void playBack(int playTime, int runUntil) 
     { 
      var frameTime = new DateTime(); var frameTime_ = new DateTime(); 

      bool fwd = true; 
      if (runUntil < playTime) fwd = false; 

      playTime = trPlay.Value; 

      playGoStop = true; 

      lbPlayTime.Text = (playTime * numDtStepSize.Value).ToString(); 

      while (true) //trPlay.Maximum + 1) 
      { 
       frameTime = DateTime.UtcNow; 
       if ((frameTime - frameTime_).TotalMilliseconds > (double)(1000/numFps.Value)) 
       { 
        systemUpdate(playTime); 
        trPlay.Value = playTime; 
        trPlay.Update(); 

        lbPlayTime.Update(); 


        frameTime_ = frameTime; 
        if (fwd) 
        { 
         playTime++; 
         if (playTime > runUntil) break; 
        } 
        else 
        { 
         playTime--; 
         if (playTime < runUntil) break; 
        } 
       } 
       if (!playGoStop) break; 
      } 
     } 
+0

Если вы можете показать соответствующие части вашего текущего кода, это будет полезно. – sstan

ответ

1

В вашем цикле while вы можете позвонить Application.DoEvents(). Он будет получать события пользовательского интерфейса из очереди событий и обрабатывать эти события. Затем будут обработаны события вашей кнопки.

Вы можете найти по ключевому слову Application.DoEvents() и C#. Об этом много вопросов.

UPDATE:

В ваших кодов, это бесконечное время как петли внутри. Я не люблю запускать бесконечное в основном потоке. Я предпочту запустить его в worker-thread. И отправьте сообщение, чтобы сделать UI обновлений в основной теме. Как правило, события UI необходимо обрабатывать в основном потоке.

Если бесконечный цикл while уже находится в worker-thread, он должен спать около 5-10 мс за цикл, чтобы освободить ресурсы ЦП для обработки некоторых событий в других потоках.

+0

Это было именно то, что мне нужно. Спасибо! –

+0

Я понятия не имею, как это сделать (отправка сообщений в часть пользовательского интерфейса).Не могли бы вы дать мне короткий пример, если у вас есть минута? –

+0

Как сказал @GEEF, или обратитесь [эта ссылка] (http://stackoverflow.com/a/1136406/419348). Вы можете вызвать 'Dispatcher.BeginInvoke()' в другом потоке, обновите UI (который запускается в основном потоке). [Или этот документ MSDN.] (Https://msdn.microsoft.com/en-us/library/cc190259 (v = vs.95) .aspx) – AechoLiu

0

Вы должны смотреть на связывание вашего UI элемента (диаграмма) данные в DependencyProperty. Это позволяет вам запускать интенсивный метод в потоке, отличном от UI, что позволяет потоку пользовательского интерфейса реагировать на нажатия кнопок. Находясь в фоновом потоке, просто сделайте Dispatcher.BeginInvoke() звонки, чтобы обновить DependencyProperty (так как он может быть обновлен только из потока пользовательского интерфейса), и это обновит ваш контроль, связанный с ним.

Что касается прерывания вашей кнопки, простым решением является установка флага из пользовательского интерфейса, который проверяется в каждой итерации цикла. Более сложным решением было бы запустить этот интенсивный метод в задаче Task, указав его CancellationTokenSource, затем отменив исходный код при нажатии кнопки.

+0

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

+0

Метод DependencyProperty не означает разгрузку в другой поток. Это просто означает, что ваш упомянутый поток (или цикл или что-то еще) может обновить DependencyProperty и привязать данные Chart к этому DependencyProperty. Это более распространенная практика WPF по сравнению с ручным обновлением диаграммы в коде. – GEEF

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