privateconstintProcessExitTimeoutMs=30*1000;// 30 seconds timeout for the process to exit.
publicstaticTask<int>ExecuteAsync(
stringcommand,
stringargs,
@ -118,7 +120,13 @@ namespace Microsoft.Tye
{
// Even though the Exited event has been raised, WaitForExit() must still be called to ensure the output buffers
// have been flushed before the process is considered completely done.
process.WaitForExit();
// Because of the bug in the dotnet runtime https://github.com/dotnet/runtime/issues/29232, Process.WaitForExit()
// hangs for processes that spawn another long-running processes.
// Since these are expected to be long running processes and we're typically not concerned with capturing all of its output
// i.e. it's probably ok for some output to be lost on shutdown, since Tye is shutting down anyway,
// we call Process.WaitForProcessExit(ProcessExitTimeoutMs).
// Also, since this is a process.Exited event, process.ExitCode is valid even if WaitForExit() times out.
process.WaitForExit(ProcessExitTimeoutMs);
}
if(throwOnError&&process.ExitCode!=0)
@ -127,6 +135,7 @@ namespace Microsoft.Tye
}
else
{
// Since the process has exited, no additional data will be written to either output buffer or error buffer, it's thread-safe to call ToString() on both outputBuilder and errorBuilder.