1

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

  • 有断点的行没有断点就不能工作
  • 它与特权无关(不像很多关于“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 生成的图像文件。

1,2 似乎执行成功了,因为我在工作目录中得到了一个png图像。

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

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

我很好奇为什么会发生这种情况。你能给我建议吗?非常感谢您提前。

4

2 回答 2

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();语句不起作用(即 gnuplot 进程在执行plot命令后没有退出),请尝试Thread.Sleep(TimeSpan.FromSeconds(1.0));(或其他一段时间)。

于 2012-10-26T04:19:39.333 回答
1

我同意门罗的观点,这是由于比赛条件造成的。除了他推荐的内容外,我建议将您的 OpenFile 方法更改为:

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

这样,如果由于任何其他原因未生成图像文件,您也将被覆盖。

于 2012-10-26T04:54:41.360 回答