避免在进程崩溃/挂起时锁定服务

本文关键字:挂起 锁定 服务 崩溃 进程 | 更新日期: 2023-09-27 18:36:31

我目前正在开发一个实现FileSystemWatcher的Windows服务。视频将上传到一个文件夹中,此时文件观察程序将触发创建的事件,如下所示以转换视频。

private void fileSystemWatcher_Created(object sender, System.IO.FileSystemEventArgs e)
{
  if (ConvertVideo(e.FullPath, e.Name))
  {
    WriteToEventLog(String.Format("Successfully converted video - {0}", e.FullPath), EventLogEntryType.Information);
  }            
}

ConvertVideo创建了一个新进程,但我遇到了进程崩溃/挂起/消失的问题,并且似乎主线程随后被锁定,因为它正在等待WaitForExit()这实际上使服务崩溃,因为没有其他视频可以转换。如果进程死亡,如何避免锁定整个服务?

private bool ConvertVideo(string SourcePath, string Filename)
{   
   try
   {
      // Create new process
      ProcessStartInfo startInfo = new ProcessStartInfo();
      startInfo.CreateNoWindow = false;
      startInfo.UseShellExecute = false;
      startInfo.FileName = "C:'Handbrake'HandBrakeCLI.exe";
      startInfo.WindowStyle = ProcessWindowStyle.Hidden;
      startInfo.Arguments = GetArguments(SourcePath, Filename);
      int? exitCode = null;
      using (Process exeProcess = Process.Start(startInfo))
      {
        exeProcess.WaitForExit();
        exitCode = exeProcess.ExitCode;
      }
   }
   catch(Exception ex)
   {
     return false;
   }
}

注意:此示例的代码已缩短

避免在进程崩溃/挂起时锁定服务

根据 MSDN,如果您的进程崩溃,Process.WaitForExit 应该返回(强调):

关联的进程退出时(即,当它被 操作系统通过正常或异常终止),系统通过 存储有关进程的管理信息并返回到 调用 WaitForExit() 的组件。

看来您的手刹过程只是挂起并保持活力。 最好的解决方案是调试该进程并找出它崩溃的位置,但不要关闭。 您是否可以访问HandBrakeCLI.exe代码?

如果您无法访问 HandBrake.exe 代码:您可以使用 Process.WaitForExit(Int32) 设置超时。如果达到超时,您可能希望通过 Process.Kill 函数手动终止您的进程,否则所有后续对 Process.Start(ProcessStartInfo) 的调用将无法正常工作,因为它们只会在进程尚未运行时返回一个新进程:

与流程资源关联的新流程组件, 如果未启动任何进程资源,则为 null(例如,如果现有的 过程被重用)。

1)您应该生成您的进程并等待它在单独的线程中终止,以避免阻塞您的主线程。

2)您可以使用 WaitForExit 方法,该方法需要等待进程的最大时间作为参数。然后,您将能够避免程序线程被永久阻塞的情况。