1

「不思議な」振る舞いが私のコードで見つかりました。簡単に言えば、ポイントは

  • ブレークポイントで機能する行は、ブレークポイントなしでは機能しませ
  • 特権とは何の関係もありません(「Win32Exception」に関する多くの質問とは異なります)

やや類似した症状がここで報告されました:MSBuildスクリプトは「Win32Exception:システムは指定されたファイルを見つけることができません」を取得します ...両方ともデバッグプロセスと関係があります。(ただし、それが私の問題と関係があるかどうかはわかりません。)

私はにコードを書いています

  1. テキスト形式でヒストグラムを作成する
  2. 「System.Diagnostics.Process.Start」を使用して「gnuplot」を起動し、生成されたヒストグラムをプロットします
  3. 'Process.Start( "generatedPlot.png")も使用して、gnuplotによって生成された画像ファイルを開きます。

作業ディレクトリにpng画像を取得したため、1,2は正常に実行されたようです。

しかし、プロット画像が存在するにもかかわらず、でファイルを開こうとすると、「指定されたファイルが見つかりませんでした」という「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'を使用して2回目の実行で例外が発生することはありません。したがって、デバッグする前に、生成されたプロットイメージを必ず削除してください。

もちろん、そこにブレークポイントを配置する以外の方法を見つけることができました。私がしたことは、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();ステートメントが機能しない場合(つまり、plotコマンドの実行後にgnuplotプロセスが終了しない場合)、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 に答える