benni_mac_b
benni_mac_b

Reputation: 8877

Avoid locking service if process crashes / hangs

I am currently developing a windows service which implements fileSystemWatcher. Videos are uploaded into a folder at which point the filewatcher fires the created event as below to convert the video.

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

Within ConvertVideo a new process is created but I have run into issues where the process crashes / hangs / disappears and it appears the main thread is then locked as its waiting for WaitForExit() which effectively crashes the service as no other videos can then be converted. How could I avoid locking the entire service if the process dies?

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

NOTE: Code is shortened for this example

Upvotes: 1

Views: 1087

Answers (2)

Jon Senchyna
Jon Senchyna

Reputation: 8047

According to MSDN, Process.WaitForExit should return if your process crashes (emphasis added):

When an associated process exits (that is, when it is shut down by the operation system through a normal or abnormal termination), the system stores administrative information about the process and returns to the component that had called WaitForExit().

It appears that your HandBrake process is just hanging and staying alive. The best solution would be to debug that process and figure out where it is crashing, but not closing down. Do you have access to the HandBrakeCLI.exe code?

If you don't have access to the HandBrake.exe code: you could use Process.WaitForExit(Int32) to set a timeout. If the timeout is reached, you may want to manually kill your process via the Process.Kill function, or all subsequent calls to Process.Start(ProcessStartInfo) will not work properly, since they will only return a new process if the process wasn'talready running:

A new Process component that is associated with the process resource, or null if no process resource is started (for example, if an existing process is reused).

Upvotes: 2

ken2k
ken2k

Reputation: 48985

1) You should spawn your process and wait for it to terminate in a separate thread, in order to avoid blocking your main thread.

2) You could use the WaitForExit method that takes the max time to wait for the process as a parameter. You'll then be able to avoid the case a thread of your program is blocked forever.

Upvotes: 1

Related Questions