連載:Windowsフォーム開発入門【Visual Studio 2010対応】
Windowsフォーム・コントロールの基礎(その3) 初音 玲2010/10/19 |
|
Windowsフォーム・コントロールを個別に説明するのも3回目を迎え、いよいよ今回でコントロールの個別説明は最終回だ。
最後に取り上げるコントロールは、以下の画面に示す、Visual Studio 2010の[ツールボックス]の[コンポーネント]タブに含まれるコントロール群だ。
図1 今回、取り上げるコントロール |
コンポーネントとは、Windowsフォーム画面のデザインにかかわるコントロールではないが、.NETのさまざまな機能を簡単に使えるようにする(Windowsフォーム画面上には表示されない)コントロール(以下、コンポーネント)のことだ。
[コンポーネント]タブには、下記のようなコンポーネントが含まれている。
(1)コンポーネント
BackgroundWorker、DirectoryEntry、DirectorySearcher、ErrorProvider、EventLog、FileSystemWatcher、HelpProvider、ImageList、MessageQueue、PerformanceCounter、Process、SerialPort、ServiceController、Timer
コンポーネントは、使い方にコツが必要だったり前提条件があったりするものが多い。そこで、比較的使用頻度が高そうなBackgroundWorker、DirectoryEntry、EventLog、FileSystemWatcher、MessageQueue、Process、Timerの7つのコンポーネントについては、具体的なコードを記載して使い方を説明したい。
■コンポーネント
●BackgroundWorkerコンポーネント
Windowsフォーム・アプリケーションで時間のかかる処理を実行していると、Windowsフォームへの操作が行えなくなり、Windowsタスク・マネージャでも「応答なし」と表示されてしまうことがある。そこで、強制的に終了せさようとすると、以下の画面のような「応答なし」の警告ダイアログが表示される。このようになってしまうのは、時間のかかる処理をしている間、Windowsフォームの再描画などUIに関係する処理もすべて「待ち」になってしまい、これがOSから見ると「応答していない」と判断されるからだ。
図2 「応答なし」の警告ダイアログ |
このような「応答なし」になってしまう現象を回避するには、時間のかかる処理を別スレッドとして(メイン・スレッドから分離して)実行し、メイン・スレッドではUIの処理が行えるようにしなければならない。別スレッドで実行させるのに、Windows.Threading名前空間の機能を直接使ってもよいが、BackgroundWorkerコンポーネント(以下、BackgroundWorker)を使うとWindows.Threading名前空間を直接使うよりも手軽に別スレッド化が行える。
BackgroundWorkerを[ツールボックス]からドラッグ&ドロップすると、Windowsフォーム・デザイナのデザイン・サーフェイスの下にあるコンポーネント・トレイに[BackgroundWorker]アイコンが配置される。
これで、BackgroundWorkerをコード中で利用できる。下記のコードはBackgroundWorkerの利用例だ。なおWindowsフォーム上には、「Background_Button」という名前のButtonコントロール(=[別スレッド実行]ボタン)と、「Status_ListBox」という名前のListBoxコントロール、「BackgroundWorker1」という名前のBackgroundWorkerを配置しているものとする。
|
||
リスト1 BackgroundWorkerの使用例(上:VB、下:C#) | ||
ButtonコントロールのClickイベント・プロシージャ(=Background_Button_Clickメソッド)は、Windowsフォーム・デザイナのフォーム画面上に配置したButtonコントロールをダブルクリックすると、そのひな型コードが自動的に生成される。同様に、BackgroundWorkerのDoWorkイベント・プロシージャ(=BackgroundWorker1_DoWorkメソッド)も、BackgroundWorker1をダブルクリックすれば自動生成される。 BackgroundWorkerのProgressChangedイベント・プロシージャ(=BackgroundWorker1_ProgressChangedメソッド)とRunWorkerCompletedイベント・プロシージャ(=BackgroundWorker1_RunWorkerCompletedメソッド)は、Windowsフォーム・デザイナのフォーム画面上に配置したBackgroundWorkerを選択した状態で、[プロパティ]ウィンドウの[イベント]一覧のそれぞれのイベント項目をダブルクリックすると自動生成される。 |
それではプログラムの動きを順番に見ていこう。
(1)Background_Button_Clickイベント・プロシージャ
[別スレッド実行]ボタンをクリックすると、Background_Button_Clickイベント・プロシージャが呼び出される。プロシージャの中では、「for each」構文を使って画面上のコントロールのEnabledプロパティを「false」に設定して、時間のかかる処理を別スレッドで実行中に新たな操作を受け付けないようにしている。もし、時間のかかる処理を実行中でもほかの操作を行えるようにしたいときは、この「for each」の部分は不要だ(ただし、[別スレッドで実行]ボタンだけは「Enabled = false」にしておいた方がいいだろう)。
次に「BackgroundWorker1.WorkerReportsProgress = true」として処理の途中経過を受け取れるようにしてから、BackgroundWorker1.RunWorkerAsyncメソッドによりBackgroundWorker経由で別スレッドを生成する。生成元のスレッドのBackground_Button_Clickイベント・プロシージャの残りのコードは、そのまま処理を続けることになる。
(2)BackgroundWorker1_DoWorkイベント・プロシージャ
別スレッドが生成されると、DoWorkイベント・プロシージャが別スレッドとして実行される。そこで、このプロシージャの中で時間のかかる処理を実行する。
(3)BackgroundWorker1_ProgressChangedイベント・プロシージャ
時間のかかる処理の中でBackgroundWorker1.ReportProgressメソッドを(処理進行度をパーセンテージでパラメータに指定して)実行すると、ProgressChangedイベントが(別スレッド側ではなく)スレッドを生成した側(つまりWindowsフォーム側)で発生する。BackgroundWorkerを使わない場合、別スレッドからWindowsフォームやコントロールを直接操作するとエラーが発生するため、デリゲート(delegate)などを使って回避しなければならないが(参考:「.NET TIPS:Windowsフォームで別スレッドからコントロールを操作するには?」)、BackgroundWorkerを使っていれば、スレッド間通信などを意識しなくて済む。
(4)BackgroundWorker1_RunWorkerCompletedイベント・プロシージャ
BackgroundWorker1_DoWorkイベント・プロシージャ内のすべての処理実行が終わり、別スレッドでの処理が完了すると、RunWorkerCompletedイベントが発生する。
BackgroundWorkerを使う利点は、ProgressChangedイベントによりスレッドをまたがってデータをやり取りできる点だろう。このサンプルでは処理進行度を渡しているが、文字データを渡すこともできる。
図3 BackgroundWorkerの実行例 |
INDEX | ||
[連載]Windowsフォーム開発入門【Visual Studio 2010対応】 | ||
Windowsフォーム・コントロールの基礎(その3) | ||
1.コンポーネント(1):BackgroundWorker | ||
2.コンポーネント(2):DirectoryEntry/DirectroySearcher/ErrorProvider/EventLog | ||
3.コンポーネント(3):FileSystemWatcher/HelpProvider/ImageList/MessageQueue | ||
4.コンポーネント(4):PerformanceCounter/Process/SerialPort/ServiceController/Timer | ||
「Windowsフォーム開発入門」 |
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|
- - PR -