【问题标题】:C# Block code till processes release handle on filesC#阻塞代码直到进程释放文件句柄
【发布时间】:2010-11-19 15:04:27
【问题描述】:

我有一个 foreach 循环,它在 try/catch 中启动一个进程。在我的 try/catch/finally 的最后部分中,我试图确保该过程没有处理任何文件。我必须删除正在处理的文件。

我尝试过的任何方法似乎都不起作用。我继续收到 System.IO 异常。 "该文件当前正被另一个进程使用。"

你可以在最后看到我在从这个方法返回之前使用了 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();
 }

【问题讨论】:

    标签: c# .net process


    【解决方案1】:

    这里有一些严重的错误。您正在启动一堆进程,但只等待最后一个产生的进程退出。

    您确定不希望 foreach 在 try 块之外吗?

    如果您告诉我们更多关于您到底想要做什么,我们可以提供更好的建议。

    【讨论】:

    • 这当然是个问题。我误解了 Start()。我的印象是原始过程被重用了。这当然可以解释为什么这个过程似乎保持开放。我将重写这一节。谢谢。
    【解决方案2】:

    我认为您需要重组代码。因为它代表foreach 中的任何进程的失败将导致退出循环。即使一切都成功了,那么您在 finally 块中的 WaitForExitClose 调用也只会处理上述循环中的最后一个进程。

    您需要单独处理每个流程及其成功和/或失败。创建一个接受fileInfo 参数并在每个进程上产生并等待的方法。将循环移动到将调用建议方法的客户端代码中。

    【讨论】:

      【解决方案3】:

      进程是控制台应用程序还是 GUI 应用程序?

      对于 GUI 应用程序,您必须执行 Process.CloseMainWindow。

      【讨论】:

        【解决方案4】:
        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. 通常最好不要在局部变量前面加上下划线字符。大多数人只是将其用于他们的领域。

        【讨论】:

          猜你喜欢
          • 2011-12-04
          • 1970-01-01
          • 2011-02-10
          • 1970-01-01
          • 2010-09-13
          • 2011-02-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多