【问题标题】:Start Process from Service hung UseShellExecute false从服务启动进程挂起 UseShellExecute false
【发布时间】:2016-11-18 15:35:26
【问题描述】:

我遇到了一件奇怪的事情,找不到发生这种情况的原因。

我有一个 service.exe,我从配置注册表中收集数据,然后启动 n 个进程。

示例代码:

_mProcess.StartInfo = new ProcessStartInfo
{
  FileName = Command,
  Arguments = Argument,
  WorkingDirectory = WorkDir
};
_mProcess.Start();
Pid = _mProcess.Id;

我的Pid 包含进程ID。

现在我添加了UseShellExecute = false 以获得标准输出。

新的示例代码:

_mProcess.StartInfo = new ProcessStartInfo
{
  FileName = Command,
  Arguments = Argument,
  WorkingDirectory = WorkDir //,
  //CreateNoWindow = true,
  UseShellExecute = false,
  //RedirectStandardOutput = true,
  RedirectStandardError = true
  //RedirectStandardInput = true
};
_mProcess.Start();
Pid = _mProcess.Id;

using (var reader = _mProcess.StandardError)
{
  _logger.ToLog("", Company, reader.ReadToEnd(), "RCluster.log", "service");
}

在这种情况下,该过程会返回我可以存储到我的日志文件中的任何错误。

问题:此代码是启动我多次调用的进程的方法的一部分(取决于我的配置)。 因此,使用此代码会调用第一个进程,而不会调用以下进程。 不知何故,服务现在等待第一个服务。我以为只有WaitForExit才会发生这种情况。

那么我怎样才能获得标准错误输出但不让进程阻止我的主要任务继续?

【问题讨论】:

  • 您的进程正在等待错误阅读器找到流结束,因此它将阻塞直到进程完成。在另一个线程或异步任务中启动错误处理。

标签: c# service backgroundworker


【解决方案1】:

@Gusman:添加你的评论作为答案,你把我带到了正确的答案。然后我可以接受您的评论作为答案。

致反对者:解释为什么会受到赞赏。

对所有人:我添加了一些代码以将新进程作为线程启动。在这种情况下,在另一个线程中启动它以获取“StandardError 消息但不阻塞主进程(在我的情况下这是一个启动许多子进程的服务)是有意义的。

      // start as new thread to prevent blocking
      var ths = new ThreadStart(() =>
      {
        mProcess.Start();
        Pid = mProcess.Id;

        // write pid file
        File.WriteAllText(RubyDir + @"\tmp\pids\" + Port + @".pid", Pid.ToString());

        using (var reader = mProcess.StandardError)
        {
          var errorMsg = reader.ReadToEnd();
          if (errorMsg.Length > 0) _logger.ToLog("", Company, errorMsg, "SOLR.log", "service");
        }
      });
      var th = new Thread(ths);
      th.Start();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    相关资源
    最近更新 更多