2010-04-29 3 views
7

У меня есть консольное приложение, которое запускается, размещает кучу сервисов (длительный запуск), а затем ждет, когда клиенты вызовут его. У меня есть интеграционные тесты, которые запускают это консольное приложение и делают «клиентские» вызовы. Как подождать, пока консольное приложение завершит запуск, прежде чем делать вызовы клиентов?Как подождать, пока консольное приложение не будет работать?

Я хочу избежать Thread.Sleep(int), потому что это зависит от времени запуска (что может измениться), и я теряю время, если запуск быстрее.

Process.WaitForInputIdle работает только с приложениями с пользовательским интерфейсом (и я подтвердил, что в этом случае это исключение).

Я открыт для неловких решений, таких как , приложению консоли написать временный файл, когда он будет готов.

+0

В консольном приложении размещены службы WCF. «Клиент» делает вызовы WCF. Если консольное приложение не завершило запуск, клиент получает исключения Endpoint Not Found. –

ответ

10

Одним из вариантов было бы создать именованный EventWaitHandle. Это создает объект синхронизации, который можно использовать для разных процессов. Затем у вас есть ваши «клиентские» приложения, до тех пор, пока событие не будет сигнализировано перед продолжением. Как только основное консольное приложение завершит запуск, оно может сигнализировать о событии.

http://msdn.microsoft.com/en-us/library/41acw8ct(VS.80).aspx

В качестве примера, ваше консольное приложение «Сервер» может иметь следующее. Это не компилируется, так это всего лишь отправная точка :)

using System.Threading; 
static EventWaitHandle _startedEvent; 
static void main() 
{ 
    _startedEvent = new EventWaitHandle(false, EventResetMode.ManualReset, @"Global\ConServerStarted"); 

    DoLongRunnningInitialization(); 

    // Signal the event so that all the waiting clients can proceed 
    _startedEvent.Set(); 
} 

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

using System.Threading; 
static void main() 
{ 
    EventWaitHandle startedEvent = new EventWaitHandle(false, EventResetMode.ManualReset, @"Global\ConServerStarted"); 

    // Wait for the event to be signaled, if it is already signalled then this will fall throught immediately. 
    startedEvent.WaitOne();  

// ... continue communicating with the server console app now ... 
} 
+2

Что делает это имя «делать»? Я использовал имя «MyCompany \ HostStarted», а консольное приложение выбрало исключение DirectoryNotFound! –

+3

Я должен был это сказать. Префикс Global \ или Local \ контролирует область действия события. Global \ делает событие «видимым» во всех сеансах, а Local \ делает его видимым только в текущем сеансе. Это важное различие, когда приложение работает на сеансе сервера терминалов, например, где вам может потребоваться использование Local \ в зависимости от ваших требований. –

+1

Это потрясающе и страшно. я люблю это. –

1

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

+0

Таким образом, приложение должно было бы проверить цикл до тех пор, пока он не вернет «я не готов к ошибке»? не уверен, что это хороший подход ... – Jack

0
  • Поскольку два (консольное приложение, и тест приложение интеграции, который делает клиент звонки - как я понимаю) это отдельное приложение, так что должен быть механизм - мост - что бы сказать играть роль посредника (сокет, внешний файл, реестр и т. д.).

  • Другая возможность может заключаться в том, что вы получаете среднее время, которое консоль берет на себя, чтобы загрузить службы и использовать это время в тестовом приложении; ну, просто вслух!

4

Как насчет установки мьютекса и его удаления после запуска. Попросите клиентское приложение подождать, пока он не сможет захватить мьютекс, прежде чем он начнет делать что-то.

+0

Подобно основному ответу, который я предоставил, однако использование EventWaitHandle позволит нескольким клиентским приложениям синхронизироваться в главном приложении. –

1

Создание службы WCF, который можно использовать для запроса о статусе серверного процесса. Запускайте эту службу только в том случае, если в командной строке передается определенная команда. Следующие признаки обеспечат очень быстрый запуск этой службы:

  • хозяина этого сервиса в качестве первой операции клиентского приложения
  • Используйте net.tcp или чистое.Труба связывания, потому что они начинают очень быстро
  • Держите эту услугу как можно проще, чтобы гарантировать, что до тех пор, как консольное приложение не завершается, он будет оставаться доступным

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

+0

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

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