2017-02-16 11 views
2

У меня есть этот код делает то, что я хочу:Ожидание результата, не блокируя поток

 TriggerSomeExternalProcess(); 
     double secondsElapsed = 0; 
     DateTime startTime = DateTime.UtcNow; 
     double timeoutInSeconds = 10; 
     while (secondsElapsed < timeoutInSeconds) { 
      // TODO: this seems bad... 
      secondsElapsed = DateTime.UtcNow.Subtract(startTime).TotalSeconds; 
     } 
     CheckStatusOfExternalProcess(); 

Цель состоит в том, чтобы TriggerSomeExternalProcess, а затем CheckStatusOfSomeExternalProcess - но этот процесс работает на том же потоке, так что я не могу сделать Thread.Sleep(). Это непрерывный процесс, которого нельзя ждать.

Я чувствую, что вышеописанный цикл while неправильный - какой шаблон вы используете, когда вам нужно ждать, не блокируя свою нить?

копия из одного ответа на один из ответов К сожалению, я не могу коснуться кода в ExternalProcess. Я пишу тест, и это те методы, к которым у меня есть доступ. Я знаю, что это меньше, чем идеал

+0

Возможный дубликат из [Асинхронно ждать Task для завершения с таймаутом] (http://stackoverflow.com/questions/4238345/asynchronously-wait-for-taskt-to-complete-with-timeout) –

+0

Использует ли таймер вариант? –

+0

@PeterBons Я так думаю. Сейчас я сделаю некоторое исследование о том, как использовать это в этом случае. – SB2055

ответ

2

Вместо использования метода CheckStatusOfExternalProcess() вы можете добавить StatusChangedEvent в объект ExternalProcess и прикрепить к нему EventHandler. Таким образом вызывается вызывающий обработчик событий, когда статус изменился.

Возможно ли это для вас?

Btw: Если оба ваших процесса работают в одной теме - как это может быть не блокировать?

+1

Спасибо Тобиас - к сожалению, я не могу коснуться кода в ExternalProcess. Я пишу тест, и это те методы, к которым у меня есть доступ. Я знаю, что это меньше идеала: p – SB2055

+0

О, это должно быть ужасно.Если у меня есть другая идея, я скажу вам;) –

+0

@ SB2055 вы должны были поместить эту информацию в свой вопрос, это очень важно – NSGaga

0

Я предполагаю, что внешний вид не является вашим собственным. Поэтому он не может принять ответное действие. Он не может дать пульс (отправьте периодически обратно его текущий статус). И он не может подписаться на его статус. Это обычные способы борьбы с этим.

В этом случае вы могли бы просто использовать что-то вроде этого

Task.delay(TimeSpan.FromSeconds(10))).ContinueWith(() => CheckStatusOfExternalProcess()) 

продолжать сгорит, как только первая задача будет завершена, но теперь вы можете продолжать в вашем коде, не заботясь об этом

+0

:) как всегда скажите мне, что заставило вас проголосовать, поэтому я могу избежать этого в будущее. –

+0

FYI Я не спустил ... – SB2055

+0

Зачем вам «StartNew» здесь? Вы можете просто «ждать Task.Delay(). ContinueWith (...)» вместо этого вы добавляете слишком много iverhead. – VMAtm