【问题标题】:Dotnet core 2 process start with timeoutDotnet core 2 进程以超时启动
【发布时间】:2018-05-11 01:50:28
【问题描述】:

我有一种方法可以从 dotnet core 2 中的 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();
    }

但我仍然有一些徘徊过程。由于多线程进程的调试非常困难,并且导致这种情况的情况对我来说是未知的,你知道为什么某些进程要摆脱我的陷阱吗?

【问题讨论】:

    标签: c# process timeout .net-core


    【解决方案1】:

    如果您使用像 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
    

    【讨论】:

      【解决方案2】:

      首先我需要对缺失的信息做出一些假设:(i) 您在 Windows 上运行代码,(ii) 您的进程没有图形用户界面(窗口)。有两种推荐的方法来停止 Windows 进程,其中首选取决于进程的类型:(i) GUI 进程,(ii) 非 GUI 进程。在第二种情况下,您应该调用Process.Kill() 方法来获得可靠的进程退出,然后立即调用Process.WaitForExit()。 Microsoft 文档指出:

      Kill 是终止没有图形界面的进程的唯一方法。

      它不会让您从清理进程资源(DisposeClose 调用)中解脱出来,但是,此任务在某种程度上与 Process.Kill() 正交,根据文档可能会导致:

      如果调用Kill,进程编辑的数据或分配给进程的资源可能会丢失。

      有很多不同的异常可能会被抛出,所以除了基本的异常处理代码之外,还有一些其他的保证。

      【讨论】:

      • 那么我应该如何在我的代码中使用您的建议?应该如何并行检查是否已达到截止日期以及如何从该并行线程(或任何东西)中终止进程。能否请您说的更清楚些。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-06
      相关资源
      最近更新 更多