情報
要求されたトピックは次のとおりです。しかし、このトピックはこのライブラリには含まれていません。

Windows Phone 8 のバックグラウンド ワーカーを使用する方法

2014/06/18

対象: Windows Phone 8 および Windows Phone Silverlight 8.1 | Windows Phone OS 7.1

Windows Phone BackgroundWorker クラスは、時間のかかる処理をバックグラウンド スレッドで簡単に実行できる方法を備えています。BackgroundWorker クラスを使用すると、処理の状態を確認したり、処理を取り消したりできます。

BackgroundWorker クラスを使用すると、Windows Phone ユーザー インターフェイスで処理の進行状況、完了、およびキャンセルを示すことができます。たとえば、バックグラウンド処理が完了したかどうか、または取り消されたかどうかを確認し、ユーザーにメッセージを表示できます。

このトピックは、次のセクションで構成されています。

BackgroundWorker クラスを使用するには

  1. クラス レベルでは、BackgroundWorker クラスのインスタンスを作成します。

    BackgroundWorker bw = new BackgroundWorker();
    
  2. バックグラウンド処理のキャンセルと進行状況の報告を許可するかどうかを指定します。

    bw.WorkerSupportsCancellation = true;
    bw.WorkerReportsProgress = true;
    
  3. バックグラウンド ワーカーの DoWork イベントのイベント ハンドラーを作成します。

    DoWork イベント ハンドラーは、時間のかかる処理をバックグラウンド スレッドで実行する場所です。バックグラウンド処理に渡した値は、DoWorkEventArgs オブジェクトの Argument プロパティでイベント ハンドラーに渡されます。

    呼び出したプロセスに進行状況を報告するには、ReportProgress メソッドを呼び出し、それに 0 ~ 100 の完了率を渡します。ReportProgress メソッドを呼び出すと、ProgressChanged イベントが発生します。これは別に処理します。

    メモメモ:

    バックグラウンド ワーカーの WorkerReportsProgress プロパティが true に設定されていない場合、ReportProgress メソッドを呼び出すと例外が発生します。

    バックグラウンド処理を取り消す要求が保留中かどうかを判別するには、BackgroundWorker オブジェクトの CancellationPending プロパティを確認します。プロパティが true の場合は、CancelAsync メソッドが呼び出されました。BackgroundWorker オブジェクトの Cancel プロパティを true に設定して処理を中止します。

    データを呼び出し元のプロセスに戻すには、イベント ハンドラーに渡される DoWorkEventArgs オブジェクトの Result プロパティを設定します。この値は、処理の終了時に RunWorkerCompleted イベントが発生すると読み取ることができます。

    
    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);
            }
        }
    }
    
    
    
  4. バックグラウンド ワーカーの ProgressChanged イベントのイベント ハンドラーを作成します。

    ProgressChanged イベント ハンドラーで、進行状況を示すコードを追加します (ユーザー インターフェイスの更新中など)。

    処理の完了率を確認するには、イベント ハンドラーに渡された ProgressChangedEventArgs オブジェクトの ProgressPercentage プロパティを調べます。

    
    private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        this.tbProgress.Text = (e.ProgressPercentage.ToString() + "%");
    }
    
    
    
  5. RunWorkerCompleted イベントのイベント ハンドラーを作成します。

    バックグラウンド ワーカーが完了すると、RunWorkerCompleted イベントが発生します。バックグラウンド処理が正常に完了したか、エラーが発生したか、取り消されたかに従って、ユーザー インターフェイスを更新します。

    エラーが発生したかどうかを確認するには、イベント ハンドラーに渡された RunWorkerCompletedEventArgs オブジェクトの Error プロパティを調べます。エラーが発生した場合は、このプロパティに例外情報が格納されています。

    バックグラウンド処理のキャンセルが許可されている場合に、処理が取り消されたかどうかを確認するには、イベント ハンドラーに渡された RunWorkerCompletedEventArgs オブジェクトの Cancelled プロパティを調べます。プロパティが true の場合は、CancelAsync メソッドが呼び出されました。

    
    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Cancelled == true)
        {
            this.tbProgress.Text = "Canceled!";
        }
    
        else if (!(e.Error == null))
        {
            this.tbProgress.Text = ("Error: " + e.Error.Message);
        }
    
        else
        {
            this.tbProgress.Text = "Done!";
        }
    }
    
    
    
  6. イベント ハンドラーを BackgroundWorker インスタンスのイベントに追加します。

    次の例は、イベント ハンドラーを DoWorkProgressChanged、および RunWorkerCompleted イベントに追加する方法を示しています。

    bw.DoWork += 
        new DoWorkEventHandler(bw_DoWork);
    bw.ProgressChanged += 
        new ProgressChangedEventHandler(bw_ProgressChanged);
    bw.RunWorkerCompleted += 
        new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
    
  7. RunWorkerAsync メソッドを呼び出して、バックグラウンド処理の実行を開始します。

    
    private void buttonStart_Click(object sender, RoutedEventArgs e)
    {
        if (bw.IsBusy != true)
        {
            bw.RunWorkerAsync();
        }
    }
    
    
    
  8. CancelAsync メソッドを呼び出して、バックグラウンド処理を取り消します。

    
    private void buttonCancel_Click(object sender, RoutedEventArgs e)
    {
        if (bw.WorkerSupportsCancellation == true)
        {
            bw.CancelAsync();
        }
    }
    
    
    

BackgroundWorker クラスを使用する方法の例を次に示します。この例では、バックグラウンド処理が Sleep メソッドを実行し、進行状況をユーザー インターフェイスに報告します。バックグラウンド ワーカーはキャンセルを許可するように設定されています。


using Microsoft.Phone.Controls;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace SL_BackgroundWorker_CS
{
    public partial class Page : PhoneApplicationPage
    {
        private BackgroundWorker bw = new BackgroundWorker();

        public Page()
        {
            InitializeComponent();

            bw.WorkerReportsProgress = true;
            bw.WorkerSupportsCancellation = true;
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        }
        private void buttonStart_Click(object sender, RoutedEventArgs e)
        {
            if (bw.IsBusy != true)
            {
                bw.RunWorkerAsync();
            }
        }
        private void buttonCancel_Click(object sender, RoutedEventArgs e)
        {
            if (bw.WorkerSupportsCancellation == true)
            {
                bw.CancelAsync();
            }
        }
        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);
                }
            }
        }
        private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled == true)
            {
                this.tbProgress.Text = "Canceled!";
            }

            else if (!(e.Error == null))
            {
                this.tbProgress.Text = ("Error: " + e.Error.Message);
            }

            else
            {
                this.tbProgress.Text = "Done!";
            }
        }
        private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.tbProgress.Text = (e.ProgressPercentage.ToString() + "%");
        }
    }
}



<phone:PhoneApplicationPage x:Class="SL_BackgroundWorker_CS.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
    shell:SystemTray.IsVisible="True">
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <StackPanel>
            <StackPanel Orientation="Horizontal" 
                        HorizontalAlignment="Left" VerticalAlignment="Top" 
                        Margin="10" >
                <Button x:Name="buttonStart" Content="Start" Click="buttonStart_Click"
                        Width="200" />
                <Button x:Name="buttonCancel" Content="Cancel" Click="buttonCancel_Click"
                        Width="200" />
            </StackPanel>
            <StackPanel Margin="10,50,0,0" Orientation="Horizontal">
                <TextBlock Text="Progress: " />
                <TextBlock x:Name="tbProgress" />
            </StackPanel>
        </StackPanel>
    </Grid>
</phone:PhoneApplicationPage>


表示: