所以我注意到有一个名为WaitForExit接受和 int 作为参数(毫秒)的方法,所以如果进程无法自行退出,我会在几秒钟后杀死它。
像这样的东西。
if (!CMD.WaitForExit(3000))
CMD.Kill();
Run Code Online (Sandbox Code Playgroud)
问题是,同时我想保存输出,所以我注意到有一个异步方法WaitForExitAsync,但这个方法不接受这些毫秒。
// Wait for exit async...
// Meanwhile save the output till it kills itself.
while (CMD.StandardOutput.ReadLine() != null)
standard_output = StandardOutput.ReadLine();
Run Code Online (Sandbox Code Playgroud)
知道如何做到这一点吗?谢谢!
你需要使用CancellationTokenSource. 它有一个接受a的ctorTimeSpan
var timeoutSignal = new CancellationTokenSource(TimeSpan.FromSeconds(3));
try
{
await CMD.WaitForExitAsync(timeoutSignal.Token);
} catch (OperationCanceledException)
{
CMD.Kill();
}
Run Code Online (Sandbox Code Playgroud)
当 CTS 发出信号时,等待的操作将抛出一个OperationCanceledException. 因此,您需要将调用await包装到try-中catch以正确处理取消的操作。
更新#1:使用退出的异步等待捕获 STDOUT
首先让我与您分享代码的幼稚版本
Console.WriteLine("Launch ping with fifteen retries");
var terminal = Process.Start(new ProcessStartInfo("/sbin/ping")
{
RedirectStandardOutput = true,
Arguments = "-c 15 stackoverflow.com",
UseShellExecute = false,
});
_ = Task.Run(() =>
{
string line = null;
while ((line = terminal.StandardOutput.ReadLine()) != null)
Console.WriteLine(line);
});
var timeoutSignal = new CancellationTokenSource(TimeSpan.FromSeconds(3));
try
{
await terminal.WaitForExitAsync(timeoutSignal.Token);
Console.WriteLine("Ping has been Finished");
}
catch (OperationCanceledException)
{
terminal.Kill();
Console.WriteLine("Ping has been Terminated");
}
Run Code Online (Sandbox Code Playgroud)
ping.exe而不是可以运行/sbin/ping命令StandardOutput阅读内容移至单独的线程 ( Task.Run)
该类Process确实公开了从 异步读取数据的功能,而StandardOutput无需执行额外的技巧
Console.WriteLine("Launch ping with fifteen retries");
var terminal = new Process()
{
StartInfo = new ProcessStartInfo("/sbin/ping")
{
RedirectStandardOutput = true,
Arguments = "-c 15 stackoverflow.com",
UseShellExecute = false,
}
};
terminal.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
terminal.Start();
terminal.BeginOutputReadLine();
var timeoutSignal = new CancellationTokenSource(TimeSpan.FromSeconds(3));
try
{
await terminal.WaitForExitAsync(timeoutSignal.Token);
Console.WriteLine("Ping has been Finished");
}
catch (OperationCanceledException)
{
terminal.Kill();
Console.WriteLine("Ping has been Terminated");
}
Run Code Online (Sandbox Code Playgroud)
让我仅强调差异
StartInfo属性OutputDataReceived事件
Data属性包含新的可用信息Start方法BeginOutputReadLine方法来告诉 Process 在标准输出上有新数据时触发上述事件处理程序