コンソール出力をWindowsフォームのテキストボックスにリダイレクトするときに問題があります。問題はスレッドに関連しています。私は、コンソールプログラムの出力をスレッドセーフな方法でテキストボックスにリダイレクトするにはどうすればよいですか?
// Handle the date received by the console process
void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
if ((e.Data.EndsWith("DONE.")) || (e.Data.EndsWith("FAILED.")) ||
(e.Data.StartsWith("RESET")))
{
// This crashes the application, but is supposedly the correct method
this.AppendText(e.Data + Environment.NewLine);
// This works, but the debugger keeps warning me that the call
// is not thread safe
//out_txtbx.AppendText(e.Data + Environment.NewLine);
}
}
}
コンソールのテキストは、このように追加され、キャプチャし、この出力ハンドラでデータを処理し、その後、次のように
private void RunConsoleApp()
{
Process proc = new Process();
proc.StartInfo.FileName = "app.exe";
proc.StartInfo.Arguments = "-a -b -c";
proc.StartInfo.UseShellExecute = false;
// set up output redirection
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.EnableRaisingEvents = true;
proc.StartInfo.CreateNoWindow = true;
// Set the data received handlers
proc.ErrorDataReceived += proc_DataReceived;
proc.OutputDataReceived += proc_DataReceived;
proc.Start();
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();
proc.WaitForExit();
if (proc.ExitCode == 0)
{
out_txtbx.AppendText("Success." + Environment.NewLine);
}
else
{
out_txtbx.AppendText("Failed." + Environment.NewLine);
}
}
をコンソールアプリケーションを実行しています
delegate void AppendTextDelegate(string text);
// Thread-safe method of appending text to the console box
private void AppendText(string text)
{
// Use a delegate if called from a different thread,
// else just append the text directly
if (this.out_txtbx.InvokeRequired)
{
// Application crashes when this line is executed
out_txtbx.Invoke(new AppendTextDelegate(this.AppendText), new object[] { text });
}
else
{
this.out_txtbx.AppendText(text);
}
}
out_txtbx.Invokeが呼び出されたときにアプリケーションがクラッシュするという点を除いて、私が見てきたすべてのドキュメントと例が正しい方法です。
何が壊れている可能性があり、これを行うための代替方法はありますか? (ハンスアンパッサンで指摘したように)
ソリューション
問題はアプリがラインの結果として、「致命的な抱擁」で立ち往生していることである、
proc.WaitForExit();
その行は削除する必要があり、その方法は次のようになります。
private void RunConsoleApp()
{
Process proc = new Process();
proc.StartInfo.FileName = "app.exe";
proc.StartInfo.Arguments = "-a -b -c";
proc.StartInfo.UseShellExecute = false;
// set up output redirection
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.EnableRaisingEvents = true;
proc.StartInfo.CreateNoWindow = true;
// Set the data received handlers
proc.ErrorDataReceived += proc_DataReceived;
proc.OutputDataReceived += proc_DataReceived;
// Configure the process exited event
proc.Exited += new EventHandler(ProcExited);
proc.Start();
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();
// This blocks the main thread and results in "deadly embrace"
// The Process.Exited event should be used to avoid this.
//proc.WaitForExit();
}
とイベントハンドラが提供されなければならない、
/// <summary>
/// Actions to take when console process completes
/// </summary>
private void ProcExited(object sender, System.EventArgs e)
{
Process proc = (Process)sender;
// Wait a short while to allow all console output to be processed and appended
// before appending the success/fail message.
Thread.Sleep(40);
if (proc.ExitCode == 0)
{
this.AppendText("Success." + Environment.NewLine);
ExitBootloader();
}
else
{
this.AppendText("Failed." + Environment.NewLine);
}
proc.Close();
}
どのようなエラーが表示されますか? – SLaks
そしてどの行に? – decyclone
私はこれを誤りなくしました。私のコードサンプルにアクセスできる時間までに適切な回答がない場合、私は投稿します。私が家に帰ると、これは今晩の後半になることに注意してください。テキストボックスに書き込んだ後、Console.SetOutをTextWriterに向けたTextWriterオブジェクトを作成しました。 http://msdn.microsoft.com/en-us/library/system.console.setout%28v=VS.90%29.aspx – IAbstract