C# 阻塞代码直到进程释放文件句柄

3
我有一个foreach循环,在try / catch中启动一个进程。在try / catch / finally的finally部分中,我正在尝试确保该进程没有占用任何文件的句柄。我必须删除正在处理的文件。

我尝试的所有方法似乎都不起作用。我仍然会收到System.IO异常:“文件当前正在被另一个进程使用。”

您可以看到在finally中,在从此方法返回之前使用了WaitForExit()。接下来的方法调用是删除文件。为什么该进程仍然打开或占用这些文件的任何句柄?

谢谢!

try
{
   foreach (var fileInfo in jsFiles)
   {
     //removed for clarity
     _process.StartInfo.FileName = "\"C:\\Program Files\\Java\\jre6\\bin\\java\"";
     _process.StartInfo.Arguments = stringBuilder.ToString();
     _process.StartInfo.UseShellExecute = false;
     _process.StartInfo.RedirectStandardOutput = true;
     _process.Start();
   }
 }
 catch (Exception e)
 {
   BuildMessageEventArgs args = new BuildMessageEventArgs("Compression Error: " + e.Message,
                                string.Empty, "JSMin", MessageImportance.High);
   BuildEngine.LogMessageEvent(args);

 }
 finally
 {
   _process.WaitForExit();
   _process.Close();
 }
4个回答

3

这里有些严重的问题。你正在启动一堆进程,但只等待最后一个被生成的进程退出。

你确定你不想将 foreach 放在 try 块之外吗?

如果你告诉我们你具体想做什么,我们可以提供更好的建议。


这肯定是个问题。我误解了Start()的作用。我以为原始进程被重复使用了。这可以解释为什么进程似乎一直保持打开状态。我将重新编写这一部分。谢谢。 - Nick

2
我认为你需要重新组织你的代码。目前这个foreach循环中的任何一个进程失败都会导致退出循环。即使所有进程都成功,你在finally块中的WaitForExitClose调用也只会处理上述循环中的最后一个进程。
你需要单独处理每个进程及其成功或失败情况。创建一个接受fileInfo参数并生成并等待每个进程的方法。将你的循环移动到将要调用建议方法的客户端代码中。

0
这个进程是控制台应用程序还是图形用户界面应用程序?
对于图形用户界面应用程序,您将需要执行Process.CloseMainWindow。

0
foreach (var fileInfo in jsFiles)
{
    using (Process process = new Process())
    {
        try
        {
            //Other stuff
            process.Start();
        }
        catch (...)
        {
            //Exception Handling goes here...
        }
        finally
        {
            try
            {
                process.WaitForExit();
            }
            catch (...)
            {
            }
        }
    }
}
  1. Process.WaitForExit() 可能会抛出异常,因此需要自己的 try/catch。
  2. 如果在 using 语句中创建进程,则无需担心关闭它,.NET 将正确处理其释放。
  3. 通常最好不要在本地变量前加下划线字符。大多数人只是用它来表示他们的字段。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接