注意この記事の最新版は「.NETのマルチスレッドプログラミング」で公開しています。.NETのマルチスレッドプログラミングについて、今号から数回にわたって説明していきます。†まずは、マルチスレッドプログラミングのはじめの一歩である、新しいスレッドを作成し、実行する方法を紹介します。マルチスレッドを使用することにより、より効率的なアプリケーションを作成できるケースが数多くあります。長く時間のかかる処理の間ユーザーインターフェイスを有効にし、ユーザーの入力に瞬時に対応する(処理中のキャンセルボタンへの対応など)ことが出来ますし、複数のURLから同時にファイルをダウンロードするようなアプリケーションを作成することも出来ます。アプリケーション」等をご覧ください。アプリケーションマルチスレッドはうまく使えば非常に便利ですが、マルチスレッドアプリケーションの作成は非常に難しく、正しく理解せずに使用することは無謀であり、絶対にやめるべきです。残念ながらこの号で私が紹介する事柄は、マルチスレッドを理解するために必要な知識の半分にも及びませんので、マルチスレッドアプリケーションをはじめて作るという方は更なる勉強が必要になると思ってください。(このメールマガジンでおいおい紹介していくつもりです。FrameworkのSystem.Threading名前空間にはマルチスレッドをサポートするいくつかのクラスが用意されています。その内最も基本的なThreadクラスによる新しいスレッドの作成と、開始の方法について説明します。マルチスレッドを用いない次のようなコンソールアプリを見てみましょう。}}このアプリはまず「スタート」と出力した後、SpendLongTimeメソッドを実行し、SpendLongTimeメソッドがすべて処理されてから、「待機中...」と表示されます(つまり出力の順番としては、「スタート」、(10秒待機)、「終わりました」、「待機中...」となります)。マルチスレッドの例として、上記コードのSpendLongTimeメソッドを別のスレッドで実行するようにしてみます。SpendLongTimeメソッドを参照するThreadStartデリゲートオブジェクトを作成し、これを使ってThreadオブジェクトを作成します。スレッドの実行を開始させるために、Thread.Startメソッドを呼び出します。ThreadStartデリゲートには引数も戻り値もありませんので、引数、戻り値のあるメソッドでは不可です。}}このアプリを実行すると、まず「スタート」と出力され、その後すぐに「待機中...」と表示し、10秒後に「終わりました」と表示されます。ここでは先のマルチスレッドを用いない例と違い、SpendLongTimeが別スレッドで開始されたため、メインスレッドがSpendLongTimeの処理でブロックされることなく、この2つのスレッドは平行して同時に(シングルプロセッサでは本当はそうではないが)実行されます。†スレッドには、フォアグラウンドスレッドとバックグランドスレッドの2種類があります。プロセス内のフォアグラウンドスレッドがすべて終了した時にそのプロセスは終了しますが(逆に言えば、すべてのフォアグラウンドスレッドが終了しなければプロセスは終了しない)、プロセス終了時に実行中のすべてのバックグランドスレッドは終了させられます(Abortが呼び出されます)。Threadオブジェクトが新しく作成、起動されたとき、そのスレッドはデフォルトでフォアグラウンドスレッドとなります。スレッドプールが使用するスレッドや、アンマネージコードからマネージ実行環境に入るスレッドは、バックグラウンドスレッドとなります。スレッドをフォアグラウンドスレッドまたはバックグラウンドスレッドにするには、Thread.IsBackgroundプロパティをfalseまたはtrueにします。具体的な例を見てみましょう。フォアグラウンドスレッドの例です。MainメソッドはMyMethod1メソッドを別スレッドで実行し、エンターキーが押されるまで待機します。MyMethod1メソッドはフォアグラウンドスレッドで実行しているため、MyMethod1メソッドが終了しなければ、エンターキーが押されてもプロセスは終了しません。}}次はバックグラウンドスレッドの例です。作成したスレッドがバックグラウンドスレッドである点を除いて前のコードと変わりありません。今度はMyMethod1メソッドをバックグラウンドスレッドで実行しているため、MyMethod1メソッドが終了する前にエンターキーを押してもすぐにプロセスが終了します。†スレッドの優先順位はThread.Priorityプロパティによって変更することが出来ます。Lowestの5段階があります。優先順位はすべてのスレッドにつけられており、Threadクラスで作成されたスレッドのデフォルトはNormalとなります。この優先順位というのは、OSによるスレッドのスケジューリングの優先順位のことです。よってその動作はOSによるということになりそうですが、一般的には優先順位のより高いスレッドの処理にプロセッサがより多くの時間を割く(より多くのプロセッサタイムスライスを割り当てる)ことになります。その結果、優先順位の低いスレッドはより高いスレッドがすべて終了する(あるいは待機状態になる)まで実行されないということにもなります。(詳しくはヘルプ「スレッドのスケジューリング」をご覧ください。)スレッドのスケジューリングこのスレッドの優先順位を利用することにより、例えば、長く時間のかかる処理の間ユーザーからの入力を待っているような場合、ユーザーからの入力待ちのためのスレッドの優先順位を高くして、その反応を良くするといったことができます。優先順位の違いにより、スレッドがどのように実行されるか具体例で見てみましょう。優先順位をつけずに(Normalのまま)2つのスレッドを作成し、実行してみます。}}結果は例えば次のようになります(スレッド1が"1"を、スレッド2が"2"を出力する)。2つのスレッドはバラバラに実行されます。(もう少しループを長くすると分かりやすくなります。)1111111111111111111111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111122222222次に、2番目に実行するスレッドに最高の優先順位であるHighestを指定して、同様に実行してみます。}}結果は例えば次のようになります。1111111111111111111111111111111111111111111111111111111111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111はじめに優先順位がNormalのスレッド"1"が開始されますが、より高い優先順位(Highest)のスレッド"2"が開始されるとそちらが優先され、スレッド"2"が終わってから再びスレッド"1"に実行が移ります。