WPFアプリケーションでTaskを用いた並列処理を実装する - TaskのサブスレッドからUIスレッドを呼び出す
WPFアプリケーションでTaskを用いた並列処理を実装するコードを紹介します。
プログラム
UI
下図のUIを作成します。ButtonとTextBoxを1つずつ配置します。
コード
下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfTaskProc
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button_Click(object sender, RoutedEventArgs e)
{
Task task = new Task(Proc);
task.Start();
}
private void Proc()
{
Action<string> msg = new Action<string>(ShowMessage);
for (int i = 0; i < 100; i++) {
System.Threading.Thread.Sleep(200);
Dispatcher.Invoke(msg, Convert.ToString(i));
}
}
private void ShowMessage(string message)
{
textBox.Text += "Message:" + message + "\r\n";
}
/*
//こちらのコードでも可
private void Proc()
{
Action<string> msg = new Action<string>(message=>{
textBox.Text += "Message:" + message + "\r\n";
});
for (int i = 0; i < 100; i++) {
System.Threading.Thread.Sleep(200);
Dispatcher.Invoke(msg, Convert.ToString(i));
}
}
*/
/*
//こちらのコードでも可
private void Proc()
{
for (int i = 0; i < 100; i++) {
System.Threading.Thread.Sleep(200);
Dispatcher.Invoke(new Action<string>(message => {
textBox.Text += "Message:" + message + "\r\n";
}), Convert.ToString(i));
}
}
*/
}
}
解説
基本的なコードは
こちらの記事で紹介している、Windows FormアプリでのTask利用コードと同じです。違いは、Windows FormではInvokeメソッドをフォームのオブジェクトのメソッドを利用していますが、WPFアプリでは、Windowクラスには、Invokeメソッドがないため、DispatcherオブジェクトのInvokeメソッドを利用します。
実行結果
プロジェクトを実行します。下図のウィンドウが表示されます。
ウィンドウの[button]をクリックします。ループで重い処理が実行されますが、ループ処理が1回実行されるごとに、テキストボックスにメッセージが表示されUIがフリーズせずに動作します。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用