У меня есть консольное приложение, которое запускается, размещает кучу служб (длительный запуск), а затем ждет, когда клиенты вызовут его. У меня есть интеграционные тесты, которые запускают это консольное приложение и делают "клиентские" вызовы. Как дождаться завершения запуска консольного приложения, прежде чем совершать клиентские вызовы?
Я не хочу делать Thread.Sleep(int), потому что это зависит от времени запуска (которое может измениться), и я теряю время, если запуск происходит быстрее.
Process.WaitForInputIdle работает только с приложениями с пользовательским интерфейсом ( и я подтвердил, что в этом случае выдается исключение).
Я открыт для неудобных решений, таких как заставить консольное приложение записать временный файл, когда он будет готов.
Ответ 1 · рейтинг 10 · Chris Taylor
Один из вариантов - создать именованный 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 ...
}
Ответ 3 · рейтинг 1 · Kyle Alons
Включите проверку готовности в клиентском интерфейсе приложения или сделайте так, чтобы оно возвращало ошибку "Не готово", если оно вызывается до того, как оно будет готово.
Ответ 4 · рейтинг 1 · Sam Harwell
Создайте службу WCF, которую можно использовать для запроса состояния серверного процесса. Запускайте эту службу только в том случае, если в командной строке передана конкретная команда. Следующие черты обеспечат очень быстрый запуск этой службы:
- Разместите эту службу в качестве первой операции клиентского приложения.
- Используйте привязку net.tcp или net.pipe, так как они запускаются очень быстро.
- Сохраняйте эту службу как можно более простой, чтобы она оставалась доступной до тех пор, пока консольное приложение не завершит работу.
Средство выполнения тестов может попытаться подключиться к этой службе. Повторите попытку, если она не удалась, пока не завершится консольное приложение или не истечет достаточно короткий период ожидания. Пока консольное приложение не завершится неожиданно, вы можете положиться на эту службу, чтобы предоставить любую дополнительную информацию перед запуском тестов в течение достаточно короткого периода времени.