BackgroundWorkerについて(WP7)

<はじめに>
ストアアプリにはasync/awaitを始めとした非同期処理は必須という話をよく聞きます。それならばWindowsPhoneだって必須だと思うのですが、やり方を知らなかったので調べてみました。どうやらBackgroundWorkerを使って処理をバックグラウンドにまわせるようです。


<プログラム>

public partial class MainPage : PhoneApplicationPage
{
    /// <summary>
    /// クラス変数
    /// </summary>
    private BackgroundWorker bw = new BackgroundWorker();

    private bool flag = true;

    #region コンストラクタ・初期化メソッド

    /// <summary>
    /// コンストラクタ
    /// </summary>
    public MainPage()
    {
        InitializeComponent();

        Initialize();
    }

    /// <summary>
    /// 初期化メソッド
    /// </summary>
    private void Initialize()
    {
        bw.WorkerReportsProgress      = true;
        bw.WorkerSupportsCancellation = true;

        bw.DoWork             += new DoWorkEventHandler(bw_DoWork);
        bw.ProgressChanged    += new ProgressChangedEventHandler(bw_ProgressChanged);
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
    }

    #endregion コンストラクタ・初期化メソッド

    #region イベント用メソッド

    /// <summary>
    /// プロセス実行用メソッド
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;

        for (int i = 1; (i <= 10); i++)
        {
            if ((worker.CancellationPending == true))
            {
                e.Cancel = true;
                break;
            }
            else
            {
                // Perform a time consuming operation and report progress.
                System.Threading.Thread.Sleep(500);
                worker.ReportProgress((i * 10));
            }
        }
    }

    /// <summary>
    /// Process完了メソッド
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if ((e.Cancelled == true))
        {
            this.textBlockProcess.Text = "Canceled!";
        }
        else if (!(e.Error == null))
        {
            this.textBlockProcess.Text = ("Error: " + e.Error.Message);
        }
        else
        {
            this.textBlockProcess.Text = "Done!";
        }
    }

    /// <summary>
    /// Processキャンセルメソッド
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        this.textBlockProcess.Text = (e.ProgressPercentage.ToString() + "%");
    }

    /// <summary>
    /// 実行ボタンクリックイベント用メソッド
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void buttonJikko_Click(object sender, RoutedEventArgs e)
    {
        if (bw.IsBusy != true)
        {
            bw.RunWorkerAsync();
        }
    }

    /// <summary>
    /// 停止ボタンクリックイベント用メソッド
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void buttonTeishi_Click(object sender, RoutedEventArgs e)
    {
        if (bw.WorkerSupportsCancellation == true)
        {
            bw.CancelAsync();
        }
    }

    /// <summary>
    /// メッセージボタンクリックイベント用メソッド
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void buttonMessage_Click(object sender, RoutedEventArgs e)
    {
        if (flag)
        {
            this.textBlockMessage.Text = "ほげ";
        }
        else
        {
            this.textBlockMessage.Text = "ふが";
        }

        flag = !flag;
    }

    #endregion イベント用メソッド

}


<まとめ>
非同期処理を使って重い処理なんかを極力バックグラウンドにまわすことで、画面が固まることを避けたいわけですが、WindowsPhone7だとこんな感じでかけますという話でした。WindowsPhone8バージョンは実機を手に入れてからぼちぼちやろうかなと。