Page4Windowsフォーム・コントロールを個別に説明するのも3回目を迎え、いよいよ今回でコントロールの個別説明は最終回だ。2010の[ツールボックス]の[コンポーネント]タブに含まれるコントロール群だ。今回、取り上げるコントロールコンポーネントとは、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から見ると「応答していない」と判断されるからだ。「応答なし」の警告ダイアログこのような「応答なし」になってしまう現象を回避するには、時間のかかる処理を別スレッドとして(メイン・スレッドから分離して)実行し、メイン・スレッドではUIの処理が行えるようにしなければならない。別スレッドで実行させるのに、Windows.Threading名前空間の機能を直接使ってもよいが、BackgroundWorkerコンポーネント(以下、BackgroundWorker)を使うとWindows.Threading名前空間を直接使うよりも手軽に別スレッド化が行える。BackgroundWorkerを[ツールボックス]からドラッグ&ドロップすると、Windowsフォーム・デザイナのデザイン・サーフェイスの下にあるコンポーネント・トレイに[BackgroundWorker]アイコンが配置される。これで、BackgroundWorkerをコード中で利用できる。下記のコードはBackgroundWorkerの利用例だ。Windowsフォーム上には、「Background_Button」という名前のButtonコントロール(=[別スレッド実行]ボタン)と、「Status_ListBox」という名前のListBoxコントロール、「BackgroundWorker1」という名前のBackgroundWorkerを配置しているものとする。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イベント・プロシージャが呼び出される。each」構文を使って画面上のコントロールのEnabledプロパティを「false」に設定して、時間のかかる処理を別スレッドで実行中に新たな操作を受け付けないようにしている。false」にしておいた方がいいだろう)。true」として処理の途中経過を受け取れるようにしてから、BackgroundWorker1.RunWorkerAsyncメソッドによりBackgroundWorker経由で別スレッドを生成する。生成元のスレッドのBackground_Button_Clickイベント・プロシージャの残りのコードは、そのまま処理を続けることになる。(2)BackgroundWorker1_DoWorkイベント・プロシージャ別スレッドが生成されると、DoWorkイベント・プロシージャが別スレッドとして実行される。そこで、このプロシージャの中で時間のかかる処理を実行する。(3)BackgroundWorker1_ProgressChangedイベント・プロシージャ時間のかかる処理の中でBackgroundWorker1.ReportProgressメソッドを(処理進行度をパーセンテージでパラメータに指定して)実行すると、ProgressChangedイベントが(別スレッド側ではなく)スレッドを生成した側(つまりWindowsフォーム側)で発生する。TIPS:Windowsフォームで別スレッドからコントロールを操作するには?」)、BackgroundWorkerを使っていれば、スレッド間通信などを意識しなくて済む。(4)BackgroundWorker1_RunWorkerCompletedイベント・プロシージャBackgroundWorker1_DoWorkイベント・プロシージャ内のすべての処理実行が終わり、別スレッドでの処理が完了すると、RunWorkerCompletedイベントが発生する。BackgroundWorkerを使う利点は、ProgressChangedイベントによりスレッドをまたがってデータをやり取りできる点だろう。このサンプルでは処理進行度を渡しているが、文字データを渡すこともできる。7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。TranslatorはPowerPoint用のアドイン。