1

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

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;
   }
}

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

4

2 回答 2

2

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

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

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

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

与流程资源关联的新流程组件,如果没有启动流程资源(例如,如果重用现有流程),则为 null

于 2012-06-08T14:26:35.853 回答
1

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

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

于 2012-06-08T14:22:58.050 回答