前回、Processで起動した別exeの標準出力をリダイレクトするアプリを作成した。
前回は標準出力を読み取るためにProcess#StandardOutput.ReadLine()メソッドを使った。
このメソッドは、標準出力があるまで現在の処理を止めてしまうため、別スレッドで実行させる必要があった。
そのため、やや複雑なプログラムを書いていた。
C#2.0から追加されたProcess#BeginOutputReadLine()メソッドを使うと、非同期に標準出力を読み取ることが出来る。
前回のプログラムを、このメソッドを使うように改良してみた。
以下に、そのプログラムを示す。
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
private Process process = null;
public Form1()
{
InitializeComponent();
}
/// <summary>
/// OnClosing処理
/// </summary>
/// <param name="e"></param>
protected override void OnClosing(CancelEventArgs e)
{
// スレッド・プロセス終了
if (process != null)
{
if (!process.HasExited)
{
process.CancelOutputRead();
process.Kill();
process.WaitForExit();
}
process = null;
}
base.OnClosing(e);
}
/// <summary>
/// ボタン押下時の処理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
if( process == null )
{
process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo("Win32ConsoleApplication");
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
process.Start();
// リダイレクトがあったときに呼ばれるイベントハンドラ
process.OutputDataReceived +=
new DataReceivedEventHandler(delegate(object obj, DataReceivedEventArgs args)
{
// UI操作のため、表スレッドにて実行
this.BeginInvoke(new Action<String>(delegate(String str)
{
if (!this.Disposing && !this.IsDisposed)
{
this.textBox1.AppendText(str);
this.textBox1.AppendText(Environment.NewLine);
}
}), new object[] { args.Data });
});
// 非同期ストリーム読み取りの開始
// (C#2.0から追加されたメソッド)
process.BeginOutputReadLine();
}
}
}
}
実行結果は前回と変わらない。

自分でスレッドを立てる処理を書かなくて良くなった分、プログラムが多少すっきりした。