У меня есть консольное приложение, которое запускает, размещает набор сервисов (продолжительный запуск) и затем ожидает клиентов для вызова в него. У меня есть интеграционные тесты, которые запускают это консольное приложение и выполняют "клиентские" вызовы. Как я ожидаю консольного приложения для завершения его запуска прежде, чем выполнить клиентские вызовы?
Я не хочу делать Thread.Sleep(int)
потому что это зависит от времени запуска (который может измениться), и я напрасно трачу время, если запуск быстрее.
Process.WaitForInputIdle
работы только над приложениями с UI (и я подтвердил, что он действительно выдает исключение в этом случае).
Я открыт для неловких решений как, имею консольное приложение, пишут временный файл, когда это готово.
Один из вариантов - создать именованный 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 ...
}
Включить проверку готовности в клиентском интерфейсе приложения или вернуть сообщение об ошибке «не готов», если оно вызывается до того, как оно будет готово.
Создайте службу WCF, которую можно использовать для запроса состояния серверного процесса. Запускайте эту службу только в том случае, если в командной строке передана определенная команда. Следующие особенности обеспечат очень быстрый запуск этой службы:
Средство выполнения тестов может попытаться подключиться к этой службе. Повторите попытку, если она не удалась, пока консольное приложение не завершится или не истечет достаточно короткий период ожидания. Пока консольное приложение не завершается неожиданно, вы можете положиться на эту службу, чтобы предоставить любую дополнительную информацию перед запуском тестов в достаточно короткий период времени.
Поскольку эти два приложения (консольное приложение и приложение для интеграционного тестирования, которое делает клиентские вызовы - как я понимаю) являются отдельными приложениями, то должен быть механизм - мост - который будет играть роль посредника (сокет, внешний файл, реестр и т.д.).
Другой возможностью может быть то, что вы вычислите среднее время, которое требуется консоли для загрузки сервисов, и используете это время в вашем тестовом приложении; ну, просто мысли вслух!
Что насчет установки мьютекса и его удаления после завершения запуска. Попросите клиентское приложение дождаться, пока оно сможет захватить мьютекс, прежде чем оно начнет что-то делать.