glued-to-code Ответов: 3

Ожидание в течение некоторого времени, пока не будет выполнено условие


У меня есть такой код, который выполняется в другом потоке, чем основной поток.
if(_isSTminStarted && (_stMinExpired == false))
            {
                //wait till stMin is expired
                String message = string.Empty;
                do
                {
                    message = "Waiting till STmin expires " + DateTime.Now.ToString("h:mm:ss.fff");
                    _logger.Info(message);
                    

                } while (_stMinExpired == false);               
           
                _isSTminStarted = true;
                _timer.STminTimerStarted(_stMinRecieved);

                CanFrame consecutiveFrame = _fragmentedFrameQueue.Dequeue();
                PublishFrame(consecutiveFrame);
            }


Пожалуйста, посмотрите цикл do while, я добавил Это, потому что мне нужно ждать, пока таймер не истечет и _stMinExpired не будет установлен в true. Тогда только я должен отправить следующий кадр.

Этот флаг устанавливается, когда истекает срок действия таймера System. threading.timer. Но я не думаю, что это идеальный способ подождать до этого времени. можете ли вы предложить некоторые способы, с помощью которых я могу ждать в этом потоке, пока этот флаг не будет установлен, а не ставить цикл do while?

walterhevedeich

Я не вижу никаких проблем в этом, если только вы не хотите регистрировать сообщение несколько раз, пока _stMinExpired не будет установлен в true.

3 Ответов

Рейтинг:
6

OriginalGriff

Воспользуйся Нить.Спать[^] вместо этого-он может подождать определенное время, прежде чем ваша задача сделает что-то еще.


glued-to-code

Но у меня нет определенного времени, до которого я должен спать. Когда таймер истекает,я должен продолжить работу в коде. Так что в этом случае я не могу поставить сон на определенное время, потому что может прийти случай, когда мне не нужно ждать, если таймер уже истек.

OriginalGriff

Поэтому вместо этого спите в течение 100 мс и проверьте еще раз, или убейте свою задачу и снова запустите ее, когда таймер истечет.

BobJanova

Это сработало бы, но события сброса лучше использовать вместо них.

glued-to-code

Спасибо вам обоим. думаю, Боб прав.

Рейтинг:
26

Firo Atrum Ventus

Попробуйте использовать AutoResetEvent[^].


glued-to-code

Да, это кажется хорошим,я могу попробовать.

BobJanova

Правильный подход, 5.

glued-to-code

Привет, спасибо Бобу и ФИРО... Это было именно то, что я хотел, и я использовал его и работает так, как я ожидал. Спасибо снова.

Рейтинг:
12

BobJanova

Как упоминает ФИРО, для этого вы хотите использовать один из обработчиков ожидания на основе событий (AutoResetEvent или ManualResetEvent). Они предназначены именно для того, о чем вы здесь просите: ждать, пока что-то не произойдет в другом потоке в неизвестное время.

class Test {
  AutoResetEvent waitHandle = new AutoResetEvent(false);

 void SpawnThread(){
  Thread t = new Thread(ThreadMethod);
  t.Start();
 }
 
 void ThreadMethod(){
  waitHandle.WaitOne();
  CanFrame consecutiveFrame = _fragmentedFrameQueue.Dequeue();
  PublishFrame(consecutiveFrame);
 }

 void SomeLongOtherMethod(){
  DoStuffThatTakesAWhile();
  waitHandle.Set(); // This will release the thread.
 }
}


Вы никогда не должны ждать, используя тугую петлю. Это приведет к запуску ядра на 100% процессоре и сделает ваше приложение непопулярным. Подождите ручки и нить.Сон также является триггером уровня ОС и переводит ваш поток в нерабочее состояние, которое не использует процессорное время.