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(); }
−以上−