Exemplo n.º 1
0
        /// <summary>
        /// De-schedule the current execution environment to sleep for some period.
        /// </summary>
        /// <param name="duration">Time to sleep.</param>
        /// <returns>Synchronization handle to continue execution after the sleep period.</returns>
        public static Result Sleep(TimeSpan duration)
        {
            Result result = new Result(TimeSpan.MaxValue);

            TaskTimerFactory.Current.New(duration, _ => result.Return(), null, TaskEnv.New());
            return(result);
        }
Exemplo n.º 2
0
        private static Yield ExecuteProcess_Helper(string application, string cmdline, Stream input, Stream output, Stream error, Result <int> result)
        {
            // start process
            var proc = new Process();

            proc.StartInfo.FileName               = application;
            proc.StartInfo.Arguments              = cmdline;
            proc.StartInfo.UseShellExecute        = false;
            proc.StartInfo.CreateNoWindow         = true;
            proc.StartInfo.RedirectStandardInput  = (input != null);
            proc.StartInfo.RedirectStandardOutput = true;
            proc.StartInfo.RedirectStandardError  = true;
            proc.Start();

            // inject input
            if (input != null)
            {
                input.CopyTo(proc.StandardInput.BaseStream, long.MaxValue, new Result <long>(TimeSpan.MaxValue)).WhenDone(_ => {
                    // trying closing the original input stream
                    try {
                        input.Close();
                    } catch { }

                    // try closing the process input pipe
                    try {
                        proc.StandardInput.Close();
                    } catch { }
                });
            }

            // extract output stream
            Result <long> outputDone = proc.StandardOutput.BaseStream.CopyTo(output, long.MaxValue, new Result <long>(TimeSpan.MaxValue));

            // extract error stream
            Result <long> errorDone = proc.StandardError.BaseStream.CopyTo(error, long.MaxValue, new Result <long>(TimeSpan.MaxValue));
            TaskTimer     timer     = TaskTimerFactory.Current.New(result.Timeout, delegate(TaskTimer t) {
                try {
                    // NOTE (steveb): we had to add the try..catch handler because mono throws an exception when killing a terminated process (why? who knows!)

                    proc.Kill();
                } catch { }
            }, null, TaskEnv.New());

            // wait for output and error streams to be done
            yield return(new AResult[] { outputDone, errorDone }.Join());

            int?exitCode = WaitForExit(proc, result.Timeout);

            timer.Cancel();
            proc.Close();
            if (exitCode.HasValue)
            {
                result.Return(exitCode.Value);
            }
            else
            {
                result.Throw(new InvalidOperationException("Unable to access process exit code"));
            }
        }