コンソールへの出力を UI に出力

Last Updated 2011/09/21


UI コントロールはそれを作成したスレッド、つまり、UI スレッド内からでしかアクセスできません。したがって、並列処理をする UI アプリケーションをテストする場合、データの出力は System.Diagnostics.Debug クラスを使うことが通常です。これでは不便ですので、Console クラスによる出力先を UI にする手順について説明します。


以下のコードの button1_Click は System.Diagnostics.Debug クラスを使うもので、出力ウインドウに出力されます。一方、button2_Click のほうは Console クラスによる出力を TextBox コントロールに出力するものです。

System.Console クラスの SetOut メソッドは指定の TextWriter オブジェクト(このオブジェクトの標準の実装クラスは System.IO.StreamWriter クラス)を出力先として指定するものです。このクラスが内部的に保持するストリームオブジェクトとして MemoryStream オブジェクトを関連付け、出力データをメモリ内に取り込みます。TextBox コントロールへの出力は System.IO.StreamReader クラスを使って MemoryStream オブジェクトから読み込みます。

private void button1_Click(object sender, RoutedEventArgs e)
{
  Parallel.For(0, 10, (n) =>
    {
      Debug.Write(String.Format("{0} ", n));
    });
}

//--------------------------------------------------------------------
private void button2_Click(object sender, RoutedEventArgs e)
{
  var buffer = new System.IO.MemoryStream();
  var writer = new System.IO.StreamWriter(buffer);

  // Console に対する出力があるたびに、データを MemoryStream へ強制的に出力する
  writer.AutoFlush = true;

  Console.SetOut(writer);

  Parallel.For(0, 10, (n) =>
    {
      Console.Write(String.Format("{0} ", n));
    });

  // ストリームの読み書き位置を先頭に戻す
  writer.BaseStream.Seek(0, System.IO.SeekOrigin.Begin);
  var reader = new System.IO.StreamReader(buffer);
  textBox.Text = reader.ReadToEnd();

  reader.Close();
  writer.Close();
}

−以上−