2012-10-26 50 views
1

A“神秘”的行为在我的代码的时候发现没有异常。简单地说,关键是神秘Win32Exception:制作一个断点

  • 与断点工作线不无断点工作
  • 它无关特权(不像很多关于'Win32Exception的提问做)

这里报告了一个有点类似的症状:MSBuild Script gets "Win32Exception: The system cannot find the File Specified" ...因为这两者都与调试过程有关。 (我不知道是否有事情做与我的问题,虽然)。

我写信给

  1. 代码生成文本格式
  2. 推出“gnuplot的”直方图通过使用' System.Diagnostics.Process.Start“绘制生成的直方图
  3. 还通过使用打开由gnuplot的生成的图像文件”的Process.Start(‘generatedPlot.png’)。

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

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

回答

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));(或一些其他时间段)来代替。

+0

非常感谢! 'p.WaitForExit()'工作!并且我证实'Thread.Sleep(TimeSpan.FromSeconds(1.0)''工作。 只是为了好玩,我也证实了我需要等待多少。原来'Thread.Sleep(TimeSpan.FromMilliseconds(200) '是门槛 - 等待199毫秒没有工作! – user23763

1

我同意门罗,这是由于竞争条件。此外,他建议什么,我建议改变你的OpenFile方法:

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

这样一来,你就还可以,如果因为任何其他原因不生成图像文件覆盖。

+0

非常感谢你!你的代码也起作用了。也就是说,如果我在调用gnuplot进程后直接调用'Process.Start(fileToOpen)',就像我发布的那样''File .exists(fileToOpen)'返回'false'。 (我的'声望'不够高,不能投票,对不起..) – user23763