プログラム

C#プログラミングレッスン

C#での .NETプログラミングを易しく丁寧に解説するメールマガジンです。「C#プログラミング・レッスン」で、.NETプログラミングをマスターしましょう。

全て表示する >

【C#プログラミングレッスン】 No.143-BackgroundWorker(1)

2007/10/09

┏━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━┳━┳━┓
┃☆┃ C#プログラミングレッスン                         ┃_┃□┃×┃
┣━┻━━━━━━━━━━━━━━━━━━━━━━━━━┻━┻━┻━┫
┃ BackgroundWorker(1)                                        No.143┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

今回から、マルチスレッドについて説明します。
まずは、.NET Framework2.0から追加されたBackgroundWorkerコンポーネント
について説明します。

■──────────────────────────────────
■ BackgroundWorkerコンポーネント

BackgroundWorkerコンポーネントは、WindowsFormsアプリケーションで利用す
るコンポーネントで、ユーザの操作をブロックせずに、時間のかかる処理を行
う時に利用します。

では、早速簡単なサンプルプログラムを作成してみましょう。

まず、フォームに、Button と Label, ListBoxを張り付けてください。

ToolBoxからBackgroundWorkerコンポーネントをフォームに張り付けて、 各プ
ロパティ、イベントを設定しても良いのですが、今回は、すべてコードで示す
ことにします。

といっても、 ボタンクリックなどのGUIのイベントハンドラは、フォームデザ
イナーで設定しています。

コードを以下に示します。各コードの意味は、コメントを参照してください。

using System;
using System.ComponentModel;
...

namespace WindowsFormsApplication1 {
    public partial class Form1 : Form {

        private BackgroundWorker worker = new BackgroundWorker();

        public Form1() {
            InitializeComponent();
            // バックグラウンドで動作するメソッドを指定します。
            worker.DoWork += worker_DoWork;
            // バックグラウンド処理が終了したら呼び出されるメソッドを
            // 指定します。
            worker.RunWorkerCompleted += worker_RunWorkerCompleted;
            // DoWorkメソッドから、GUIを操作したいときに利用する
            // メソッドを指定します。
            worker.ProgressChanged += worker_ProgressChanged;
            // true にすると、ProgressChanged が有効になります。
            worker.WorkerReportsProgress = true;
        }

        void worker_RunWorkerCompleted(object sender,
                                       RunWorkerCompletedEventArgs e) {
            label1.Text = "終了しました";
        }

        // 時間のかかるバックグラウンド処理
        private void worker_DoWork(object sender, DoWorkEventArgs e) {
            BackgroundWorker bw = (BackgroundWorker)sender;
            for ( int i = 0; i < 20; i++ ) {
                // 当サンプルの効果が良くわかるように、処理をWait
                System.Threading.Thread.Sleep(300);
                // ここで、ListBoxを更新するために、ReportProgress を
                // 呼び出します。
                // worker_ProgressChanged メソッドが間接的に呼び出され
                // ます。
                // このメソッド内で、直接 GUIコントロールを操作してはい
                // けません。
                bw.ReportProgress(0, i);
            }
        }

        // ListBox を更新 (メインスレッド上で動作する)
        private void worker_ProgressChanged(object sender,
                                        ProgressChangedEventArgs e) {
            int i = (int)e.UserState;
            listBox1.Items.Add("Item " + i.ToString());
        }

        private void button1_Click(object sender, EventArgs e) {
            // バックグラウンド処理を開始
            this.worker.RunWorkerAsync();
        }

        // ListBoxをクリックしたときの処理。
        private void listBox1_SelectedIndexChanged(object sender,
                                                   EventArgs e) {
            ListBox lb = (ListBox)sender;
            label1.Text = lb.SelectedItem.ToString();
        }
    }
}

このプログラムを起動し、 ボタンをクリックすると、ListBoxにゆっくりと行
が追加されていきますので、そこで、適当な行をクリックしてみてください。
クリックに反応し、Labelの表示が変わるのが確認できると思います。
通常、時間のかかる処理を記述すると、その間、フォームに対して操作が行え
ませんが、BackgroundWorkerコンポーネントを使うことで、比較的簡単にユー
ザの操作をブロックしないプログラムを書くことができます。

補足
ProgressChanged、ReportProgress という名前からわかるように、動作の進行
状況を表示するプログレス表示に利用されることを想定しています。
後ほど、プログレス表示の例も示したいと思います。

┌─┬─────────────────────────┬─┬─┬─┐
│☆│ C#プログラミングレッスン  (ぼぼ週刊)            │_│□│×│
├─┴─────────────────────────┴─┴─┴─┤
│ Published by Gushwell.                                           │
│ Copyright (C) 2004-2007 Gushwell All rights reserved.            │
│ Microsoft MVP Visual Developer - Visual C#(Apr 2005 - Mar 2008)  │
│-------------------- Gushwell's Page ---------------------------- │
│ 窓際プログラマーの独り言  :http://blog.livedoor.jp/gushwell/    │
│ 窓際プログラマーの読書三昧:http://gushwell.jugem.jp/            │
│ Gushwell's C# Programing Page:http://gushwell.ifdef.jp/         │
│ C#デザインパターン :                                             │
│  『増補改訂版Java言語で学ぶデザインパターン入門 / 結城 浩(著)』  │
│   のサンプルコードをC#に移植したものを掲載しています。           │
│   移植後のコードの公開は、結城氏の了解を得ています。             │
│   http://blog.livedoor.jp/gushwell/archives/50333227.html        │
└─────────────────────────────────┘

規約に同意してこのメルマガに登録/解除する

メルマガ情報

創刊日:2004-08-12  
最終発行日:  
発行周期:ほぼ週刊  
Score!: 非表示   

コメント一覧コメントを書く

この記事にコメントを書く

上の画像で表示されている文字を半角英数で入力してください。

※コメントの内容はこのページに公開されます。発行者さんだけが閲覧できるものではありません。 コメントの投稿時は投稿者規約への同意が必要です。

  • コメントはありません。