2012-06-08 39 views
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; 
    } 
} 

注:代码被缩短这个例子

+0

任何带有完整源代码的最终解决方案? – Kiquenet

回答

2

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

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

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

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

与进程资源关联的新进程组件 或如果没有进程资源启动(例如,如果现有的 进程被重用),则返回null

+0

这很有趣,不能调试Handbrake代码,但可能能够将其视为其开源应用程序。 http://handbrake.fr/downloads2.php我查看了waitforExit()的提示,但肯定没有提到。这可能是解决方案。 –

1

1) 你应该产卵的过程,并等待它在一个单独的线程终止,为了避免阻塞主线程。

2) 您可以使用WaitForExit method that takes the max time to wait for the process as a parameter。然后你就可以避免你的程序中的一个线程永远被阻塞。

+0

嗨,我已经看过第二个建议,但由于一些视频可能很大(高达100MB),超时时间需要非常大,尽管线程并没有永久封锁,但它已锁定了很长时间。任何有关线程化流程的最佳方法的建议? –

+0

如果为该调用生成另一个线程,则仍需要确保在再次调用Process.Start之前等待该过程完成。如果您的进程已经运行,Process.Start将返回null。 –