因此,我注意到有一个名为WaitForExit
的方法,它接受作为参数的int (毫秒),因此如果进程无法退出自身,那么几秒钟后我就会将其关闭。
就像这样。
if (!CMD.WaitForExit(3000))
CMD.Kill();
问题是,同时我想保存输出,所以我注意到有一个异步方法WaitForExitAsync
,但这个方法不接受这些毫秒。
// Wait for exit async...
// Meanwhile save the output till it kills itself.
while (CMD.StandardOutput.ReadLine() != null)
standard_output = StandardOutput.ReadLine();
知道怎么做吗?谢谢!
发布于 2022-01-07 13:40:11
您需要使用CancellationTokenSource
。它有一个克托尔,它接受一个TimeSpan
var timeoutSignal = new CancellationTokenSource(TimeSpan.FromSeconds(3));
try
{
await CMD.WaitForExitAsync(timeoutSignal.Token);
} catch (OperationCanceledException)
{
CMD.Kill();
}
当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");
}
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");
}
我只想强调一下不同的地方
StartInfo
属性,而不是立即启动该进程。OutputDataReceived
事件。Data
属性包含新的可用信息Start
方法BeginOutputReadLine
方法来告诉进程,每当标准输出上有新数据可用时,就会触发上面的事件处理程序。https://stackoverflow.com/questions/70622033
复制相似问题