マルチスレッド アプリケーション (C# および Visual Basic)

Visual Basic および C# では、複数のタスクを同時に実行するアプリケーションを作成できます。他のタスクを停止させる可能性のあるタスクは別のスレッドで実行できます。これは、マルチスレッドまたはフリー スレッドと呼ばれるプロセスです。

マルチスレッドを使用するアプリケーションでは、プロセッサ集中型のタスクを別のスレッドで実行している間もユーザー インターフェイスがアクティブに保たれるため、ユーザー入力に対する応答性がより高くなります。マルチスレッドは、作業負荷が増加すると同時にスレッドを追加できるため、スケーラブルなアプリケーションを作成するときにも役立ちます。

[!メモ]

Visual Studio 2010 および .NET Framework 4 では、新しいランタイム、新しいクラス ライブラリの型、および新しい診断ツールを提供することで、並列プログラミングのサポートを強化しています。詳細については、「.NET Framework の並列プログラミング」を参照してください。

BackgroundWorker コンポーネントの使用

マルチスレッド アプリケーションを作成する最も信頼性の高い方法は、BackgroundWorker コンポーネントを使うことです。このクラスは、指定したメソッドのみを処理する独立したスレッドを管理します。例については、「チュートリアル: BackgroundWorker コンポーネントでのマルチスレッド (C# および Visual Basic)」を参照してください。

処理をバックグラウンドで開始するには、BackgroundWorker を作成し、処理の進行の報告と、処理が完了した時点の通知をするイベントを待機します。BackgroundWorker オブジェクトは、プログラムで作成できます。また、ツールボックス[コンポーネント] タブからフォーム上にドラッグすることもできます。BackgroundWorkerフォーム デザイナーで作成すると、このオブジェクトがコンポーネント トレイに表示され、そのプロパティが [プロパティ] ウィンドウに表示されます。

バックグラウンド処理のセットアップ

バックグラウンド処理をセットアップするには、DoWork イベントにイベント ハンドラーを追加します。時間のかかる処理は、このイベント ハンドラーの内部で呼び出します。

処理を開始するには、RunWorkerAsync を呼び出します。更新の進行状況に関する通知を受け取るには、ProgressChanged イベントを処理します。処理完了の通知を受け取るには、RunWorkerCompleted イベントを処理します。

ProgressChanged イベントと RunWorkerCompleted イベントは RunWorkerAsync メソッドの呼び出し元のスレッドに生成されるので、これらのイベントを処理するメソッドは、アプリケーションのユーザー インターフェイスにアクセスできます。ただし、DoWork イベント ハンドラーは、バックグラウンド スレッドで動作するので、ユーザー インターフェイス オブジェクトと共に操作することはできません。

スレッドの作成と使用

アプリケーションのスレッドの動作をもっと細かく制御する必要がある場合は、スレッドそのものを管理します。ただし、マルチスレッド アプリケーションを正しく作成することは簡単ではありません。競合状態の発生によってアプリケーションが応答しなくなることや一時的なエラーが発生することがあります。詳細については、「スレッドセーフ コンポーネント」を参照してください。

新規スレッドを作成するには、Thread 型の変数を宣言し、新規スレッドで実行するプロシージャ名またはメソッド名を指定してコンストラクターを呼び出します。次にコード例を示します。

Dim newThread As New System.Threading.Thread(AddressOf AMethod)
System.Threading.Thread newThread =
    new System.Threading.Thread(AMethod);

ck8bc5c6.collapse_all(ja-jp,VS.110).gifスレッドの開始と停止

新規スレッドの実行を開始するには、次のコードに示すように Start メソッドを使用します。

newThread.Start()
newThread.Start();

スレッドの実行を停止するには、次のコードに示すように Abort メソッドを使用します

newThread.Abort()
newThread.Abort();

スレッドの開始と停止のほか、Sleep メソッドまたは Suspend メソッドを呼び出してスレッドを一時停止したり、中断しているスレッドを Resume メソッドを使用して再開したり、Abort メソッドを使用してスレッドを破棄したりできます。

ck8bc5c6.collapse_all(ja-jp,VS.110).gifスレッドのメソッド

個別のスレッドを制御するために使用できるメソッドの一部を次の表に示します。

メソッド

動作

Start

スレッドの実行を開始します。

Sleep

スレッドを一定の時間中断します。

Suspend

セーフ ポイントに達したスレッドを一時中断します。

Abort

セーフ ポイントに達したスレッドを中断します。

Resume

中断しているスレッドを再開します。

Join

別のスレッドが終了するまで現在のスレッドを待機させます。タイムアウト値を指定してこのメソッドを使用すると、指定の時間内でスレッドが終了した場合、True が返されます。

ck8bc5c6.collapse_all(ja-jp,VS.110).gifセーフ ポイント

これらのメソッドの大部分は自明ですが、セーフ ポイントは新しい概念です。セーフ ポイントとは、共通言語ランタイムが自動ガベージ コレクション、つまり不要な変数を解放し、メモリを再要求するプロセスを安全に実行できるコード内の場所です。スレッドの Abort メソッドまたは Suspend メソッドを呼び出すと、共通言語ランタイムがコードを分析し、スレッドの実行を停止してもよい場所を探します。

ck8bc5c6.collapse_all(ja-jp,VS.110).gifスレッドのプロパティ

スレッドには、次の表に示すように、複数の便利なプロパティが用意されています。

プロパティ

IsAlive

スレッドがアクティブな場合、値は True です。

IsBackground

スレッドがバックグランウンド スレッドであるかどうかを示す、ブール型を取得または設定します。バックグラウンド スレッドは、フォアグラウンド スレッドと似ていますが、プロセスの終了を防止しません。プロセスに属するフォアグラウンド スレッドがすべて終了すると、共通言語ランタイムは、まだ動作しているバックグラウンド スレッドの Abort メソッドを呼び出してプロセスを終了します。

Name

スレッドの名前を取得または設定します。デバッグ時の個別のスレッドの検出に、最もよく使用されます。

Priority

オペレーティング システムがスレッドのスケジュールに優先順位を示す値を取得または設定します。

ApartmentState

特定のスレッドに使用するスレッド モデルを取得または設定します。スレッド モデルは、スレッドがアンマネージ コードを呼び出すときに重要です。

ThreadState

スレッドの状態を記述する値です。

スレッドの優先順位

各スレッドには、実行するプロセッサ時間のスライスの大小を指定する Priority プロパティがあります。オペレーティング システムは、優先順位の高いスレッドに長いタイム スライスを割り当て、優先順位の低いスレッドに短いスライスを割り当てます。新しいスレッドは Normal 値で作成されますが、Priority プロパティは ThreadPriority 列挙の任意の値に変更できます。

さまざまなスレッド優先順位の詳細については、「ThreadPriority」を参照してください。

フォアグラウンド スレッドとバックグラウンド スレッド

フォアグラウンド スレッドは無期限に実行されますが、バックグラウンド スレッドは最後のフォアグラウンド スレッドが停止すると終了します。IsBackground プロパティを使用すると、スレッドのバックグラウンド ステータスを指定または変更できます。

フォームとコントロールでのマルチスレッド

マルチスレッドはプロシージャとクラス メソッドの実行に最適ですが、フォームとコントロールでも使用できます。その場合は、以下の点に注意してください。

  • コントロールのメソッドは、できる限りそのコントロールが作成されたスレッドだけで実行してください。コントロールのメソッドを別のスレッドから呼び出す必要がある場合は、Invoke を使用してメソッドを呼び出す必要があります。

  • SyncLock ステートメント (Visual Basic) または lock ステートメント (C#) を使用してコントロールまたはフォームを操作するスレッドをロックしないでください。コントロールとフォームのメソッドは呼び出しプロシージャをコールバックする場合があるため、誤ってデッドロック状態が発生することがあります。デッドロック状態になると 2 つのスレッドが互いにロックの解放を待機するため、アプリケーションが停止します。

参照

関連項目

スレッドの同期 (C# および Visual Basic)

Invoke

InvokeRequired

Thread

概念

マルチスレッド プロシージャのパラメーターと戻り値 (C# および Visual Basic)

その他の技術情報

コンポーネントのマルチスレッド

Visual C# を使用してスレッドを作成する方法