public async Task <bool> StartAsync() { MonitoringSuspended = true; EnsureDead(Process); string commandLineArgs = string.Empty; string executablePath = ExecutablePath; try { if (Port < 0) { Port = GrpcUtils.GetFreeTcpPort(); } commandLineArgs = CommandLineArguments? .Replace("{HostName}", HostName) .Replace("{Port}", Port.ToString()); executablePath = GetActualExePath(); _logger.LogInformation( "Starting {executablePath} with parameters {commandLineArgs}...", executablePath, commandLineArgs); Process = ProcessUtils.StartProcess(executablePath, commandLineArgs, false, true, EnvironmentVariables); // Very important. Otherwise the process hangs once the buffer is full. Process.BeginOutputReadLine(); Process.BeginErrorReadLine(); double startupWait = StartupWaitSeconds == 0 ? _defaultStartupWait : StartupWaitSeconds; TimeSpan startupWaitTime = TimeSpan.FromSeconds(startupWait); _logger.LogDebug("Configured startup wait time is {startupWaitSeconds}s...", startupWait); // Let the process start the services... await Task.Delay(startupWaitTime); bool healthy = await IsServingAsync(); if (healthy) { _logger.LogInformation("Successfully started {process}", this); } else { _logger.LogWarning("Startup of {process} has failed", this); } return(healthy); } catch (Exception e) { string errorMessage = e.Message; _logger.LogError(e, "Error starting {ExecutablePath} with parameters {CommandLineArguments}: {errorMessage}", executablePath, commandLineArgs, errorMessage); return(false); } finally { MonitoringSuspended = false; } }