我有一个方法可以在dotnet core2中从我的c#代码启动进程。这个方法类似于:
internal static string[] RunCommand(string filename, string args, string workingDirectory = null)
{
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = filename,
Arguments = args,
UseShellExecute = false,
RedirectStandardOutput = true,
//WindowStyle = ProcessWindowStyle.Hidden
}
};
if (workingDirectory != null)
{
proc.StartInfo.WorkingDirectory = workingDirectory;
}
//Console.WriteLine(proc.StartInfo.FileName + " " + proc.StartInfo.Arguments);
List<string> lines = new List<string>();
proc.Start();
while (!proc.StandardOutput.EndOfStream)
{
string line = proc.StandardOutput.ReadLine();
if (!string.IsNullOrEmpty(line))
{
lines.Add(line);
}
}
proc.Dispose();
return lines.ToArray();
}问题是,一些启动的进程陷入循环,这让我的vps遇到了问题。
所以问题是,有没有解决方案来运行一个有截止日期的进程?
更新
根据'Jacek Blaszczynski‘的建议,我尝试了下面的代码:
internal static string[] RunCommand(string filename, string args, string workingDirectory = null, int timeoutInSeconds = 60)
{
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = filename,
Arguments = args,
UseShellExecute = false,
RedirectStandardOutput = true,
//WindowStyle = ProcessWindowStyle.Hidden
}
};
if (workingDirectory != null)
{
proc.StartInfo.WorkingDirectory = workingDirectory;
}
//Console.WriteLine(proc.StartInfo.FileName + " " + proc.StartInfo.Arguments);
List<string> lines = new List<string>();
bool isKilled = false;
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
Thread.Sleep(timeoutInSeconds * 1000);
try
{
if (proc != null && !proc.HasExited)
{
isKilled = true;
proc.Kill();
Console.WriteLine("Annoying process killed.");
}
}
catch
{
// just let it go
}
}).Start();
try
{
proc.Start();
while (!proc.StandardOutput.EndOfStream)
{
string line = proc.StandardOutput.ReadLine();
if (!string.IsNullOrEmpty(line))
{
lines.Add(line);
}
}
proc.Dispose();
}
catch
{
// just look what happens
}
return isKilled ? new string[] { "" } : lines.ToArray();
}但我仍然有一些wander进程。由于多线程进程的调试非常困难,导致这种情况的情况对我来说也是未知的,你知道为什么一些进程要从我的陷阱中跑出来吗?
发布于 2020-10-09 23:27:34
如果使用像CliWrap这样的库,则可以简化这一过程
using CliWrap;
using CliWrap.Buffered;
// Timeout setup
using var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromMinutes(1));
// Run the process
var result = await Cli.Wrap("path/to/exe")
.WithArguments("--foo bar")
.ExecuteBufferedAsync(cts.Token);
// The process will be killed automatically if the execution is cancelled发布于 2017-11-28 07:23:48
首先,我需要对丢失的信息做一些假设:(i)您在Windows上运行代码,(ii)您的进程没有图形用户界面(窗口)。有两种建议的方法来停止Windows进程,其中首选的选择取决于进程类型:(i) GUI进程,(ii)非GUI进程。在第二种情况下,您应该调用Process.Kill()方法以获得可靠的进程退出,然后立即调用Process.WaitForExit()。Microsoft文档指出:
终止是终止没有图形界面的进程的唯一方法。
它不会让您从清理进程资源(Dispose或Close调用)中解脱出来,但是,此任务在某种程度上与Process.Kill()是正交的,根据文档,这可能导致:
如果调用Kill,则由进程编辑的
数据或分配给进程的资源可能会丢失。
有许多不同的异常可能会被抛出,所以除了基本的异常处理代码之外,还需要更多的异常。
https://stackoverflow.com/questions/47517455
复制相似问题