神秘的Win32Exception:在创建断点时不会抛出

时间:2012-10-26 01:09:50

标签: c# visual-studio-2012

我的代码中发现了“神秘”的行为。简而言之,重点是

  • 使用断点的行没有断点
  • 它与权限无关(不像很多关于'Win32Exception'的问题)

这里报告了一个类似的症状:MSBuild Script gets "Win32Exception: The system cannot find the File Specified" ...因为两者都与调试进程有关。 (不过我不确定它是否与我的问题有关。)

我正在编写代码

  1. 以文本格式生成直方图
  2. 使用'System.Diagnostics.Process.Start'绘制生成的直方图来启动'gnuplot'
  3. 也使用'Process.Start(“generatedPlot.png”)打开gnuplot生成的图像文件。
  4. 1,2似乎成功执行,因为我在工作目录中获得了一个png图像。

    然而,尽管存在绘图图像,但当我尝试使用

    打开文件时,我得到一个'Win32Exception'说“找不到指定的文件”
    void GeneratePlot()
    {
      // generate a png image called 'outputPath' with console 'gnuplot.exe'
      MyClass.gnuplot(dataFilePath,outputPath);
      MyClass.OpenFile(outputPath);
    }
    

    OpenFile简单定义为

    static void OpenFile(string fileToOpen)
    {
      Process.Start(fileToOpen);  // this throws 'Win32Exception'  ...(*)
    }
    

    神秘之处在于:为了调试这个问题,我将作为(*)的断点。然后异常不再抛出!

    (注意:因为绘图图像是成功创建,所以在第二次运行时不会出现具有相同'fileToOpen'的异常。因此,请确保删除调试前生成的绘图图像。

    当然,我设法找到了一种方法,而不是在那里放置一个断点。我所做的只是分离MyClass.gnuplot和MyClass.OpenFile的执行:

    void GeneratePlot()
    {
      // some code
      MyClass.gnuplot(dataFilePath, outputPath);
    }
    
    void button1_Click(object sender, EventArgs e)
    {
      MyClass.OpenFile(outputPath);
    }
    

    执行'GeneratePlot()'后,点击'button1'。 这次显示了png图像!

    为了以防万一,我写了一个像这样的代码来创建一个png情节图像:(单独工作很好!)

    static void gnuplot(string dataFilePath, string outputPath)
    {
      Process p = new Process();
      p.StartInfo.FileName = \\path\\to\\gnuplot.exe;
      p.StartInfo.RedirectStandardInput = true;
      p.StartInfo.WorkingDirectory = Directory.GetWorkingDirectory();
      // some other StartInfo setting
      p.Start();
    
      // execute gnuplot with the following
      StreamWriter sw = new StreamWriter(p.StandardInput);
      sw.WriteLine("set terminal \"png\"");
      sw.WriteLine("set output " + outputPath);
      sw.WriteLine("plot '{0}'",dataFilePath);
    }
    

    我很好奇为什么会这样。你能给我建议吗?非常感谢你提前。

2 个答案:

答案 0 :(得分:1)

在gnuplot创建和写入文件的时间与您尝试在自己的进程中打开文件的时间之间可能存在竞争条件。我敢打赌,当你在调试器中运行它时,到达断点的时候已经过了足够的时间,gnuplot进程已经关闭了输出文件。

要解决此问题,您可以在发送plot命令后等待一段时间,或者更好的是,等待gnuplot进程退出。

static void gnuplot(string dataFilePath, string outputPath)
{
  Process p = new Process();
  p.StartInfo.FileName = \\path\\to\\gnuplot.exe;
  p.StartInfo.RedirectStandardInput = true;
  p.StartInfo.WorkingDirectory = Directory.GetWorkingDirectory();
  // some other StartInfo setting
  p.Start();

  // execute gnuplot with the following
  StreamWriter sw = new StreamWriter(p.StandardInput);
  sw.WriteLine("set terminal \"png\"");
  sw.WriteLine("set output " + outputPath);
  sw.WriteLine("plot '{0}'",dataFilePath);

  // ----> wait for gnuplot to exit before returning
  // (presumes that gnuplot exits shortly after executing the plot command)
  p.WaitForExit();
}

如果p.WaitForExit();语句不起作用(即,在执行plot命令后gnuplot进程没有退出),请尝试Thread.Sleep(TimeSpan.FromSeconds(1.0));(或其他一段时间)代替。

答案 1 :(得分:1)

我同意梦露这是因为竞争条件。除了他推荐的内容之外,我建议将OpenFile方法更改为:

if (System.IO.File.Exists(fileToOpen))
{
    Process.Start(fileToOpen);
}
else
{
    // handle missing file scenario
}

这样,如果由于任何其他原因未生成图像文件,您也会受到保护。