예제 #1
0
        public async Task <bool> WaitForExitAsync(TimeSpan timeout, CancellationToken token = default)
        {
            var sw = Stopwatch.StartNew();

loop:
            if (token.IsCancellationRequested)
            {
                return(false);
            }

            if (m_process != null)
            {
                int pid = m_process.Id;
                if (!await m_process.WaitForExitAsync(timeout, token).ConfigureAwait(false))
                {
                    return(false);
                }

                if (m_options.RestartAfterCrash && pid != m_process.Id)
                {
                    // Process has been restarted. The "OnExit()" method is called during
                    // WaitForExit(). So technically, the process has exited, but has been
                    // restarted while the user has been waiting for it. So from the user's
                    // point if view it is still running.
                    // Account for total wait time, if any, and continue waiting.

                    m_options.Events.OnHostRestart(pid, m_process.Id);

                    if (timeout != TimeSpan.Zero)
                    {
                        timeout = timeout.Add(-sw.Elapsed);

                        if (timeout <= TimeSpan.Zero)
                        {
                            return(false);
                        }
                    }

                    goto loop;
                }

                int exitCode = m_process.ExitCode;
                if (exitCode != 0)
                {
                    if (!m_options.Events.OnHostExitWithError(pid, exitCode))
                    {
                        throw new IsolationException(string.Format(CultureInfo.InvariantCulture,
                                                                   "Host process failed with code {0}",
                                                                   ProcessUtils.GetExitCodeDescription(exitCode)));
                    }
                }
            }

            return(true);
        }