スレッドはプログラムの実行パスとして定義されます。各スレッドは固有のフロー制御を定義します。アプリケーションにデータベース アクセスや集中的な I/O 操作など、複雑で時間のかかる操作が含まれる場合は、異なる実行パスまたはスレッドを設定し、各スレッドが特定のジョブを実行することが非常に有益であることがよくあります。
スレッドは軽量プロセスです。スレッドの一般的な使用例は、最新のオペレーティング システムでの並列プログラミングの実装です。スレッドを使用すると、CPU サイクルの損失が節約され、アプリケーションの効率が向上します。
これまでにコンパイルしたプログラムは、アプリケーションの実行インスタンスであるスレッド上で単一のプロセスとして実行されます。ただし、そのようなアプリケーションは一度に 1 つのジョブしか実行できません。複数のタスクを同時に実行するには、より小さなスレッドに分割します。
.Net では、スレッドは「System.Threading」名前空間を通じて処理されます。 system.threading.thread 型の変数を作成すると、新しいスレッドを作成して作業を開始できます。これにより、別のスレッドで独立したスレッドを作成してアクセスできるようになります。
スレッドはスレッド オブジェクトから作成され、そのコンストラクターにはスレッドを開始するための参照が与えられます。
ThreadStart childthreat = new ThreadStart(childthreadcall);
スレッドのライフサイクルは、system.threading.thread クラスのオブジェクトが作成されたときに始まり、スレッドが終了するか実行が完了したときに終了します。
スレッドのライフサイクルにおけるさまざまな状態を次に示します。
開始保留状態:スレッドのインスタンスは作成されましたが、開始メソッドが呼び出されていません。
準備完了状態:スレッドが実行の準備ができており、CPU サイクルを待っている状態。
実行不能状態:スレッドを実行できない場合は、いくつかの可能性が考えられます。
現在のスリープ メソッドは次のように呼ばれます。
待機メソッドが呼び出される
I/O操作によりブロックされました
停止状態:スレッドは実行を完了したか、終了しました。
Thread クラスの priority 属性は主に、他のスレッドに対するスレッドの優先度を指定します。 .NET ランタイムは、最高の優先順位を持つ準備完了スレッドを選択します。優先順位は次のように分類できます。
通常よりも高い
通常より低い
最高
最低
普通
スレッドが作成されると、システムは Thread クラスの優先順位設定システムを使用してその優先順位を設定します。
NewThread.Priority = ThreadPriority.Highest;
スレッド クラスには次の重要な機能があります。
財産 | 説明する |
---|---|
現在のコンテキスト | 現在実行中のスレッドの内容を取得します。 |
現在の文化 | 現在のスレッドの環境を取得または設定します。 |
現在の原則 | 現在のプロセスのロールベースのセキュリティ ポリシーを取得または設定します。 |
現在のスレッド | 現在実行中のスレッドを取得します。 |
現在のUI文化 | 現在実行中のプロセスのリソース マネージャーが特定のリソースを検索するために使用する現在の環境を取得または設定します。 |
実行コンテキスト | 現在のスレッドに関するコンテキスト情報を含む ExecutionContext オブジェクトを取得します。 |
生きている | 現在のスレッドの実行ステータスを示す値を取得します。 |
背景です | Background スレッドがバックグラウンド スレッドであるかどうかを示す値を取得または設定します。 |
スレッドプールスレッド | スレッドがマネージド スレッド プールに属しているかどうかを示す値を取得します。 |
管理対象スレッドID | マネージド スレッドの現在の一意の識別子を取得します。 |
名前 | スレッドの名前を取得または設定します。 |
優先度 | スレッドのスケジュール優先度を示す値を取得または設定します。 |
スレッド状態 | 現在のスレッドのステータスを含む値を取得します。 |
スレッド クラスには次の重要なメソッドがあります。
方法 | 説明する |
---|---|
アボート | ThreadAbortException を呼び出すと、スレッドを終了するプロセスが開始されます。このメソッドを呼び出すと、通常、スレッドが終了します。 |
データスロットの割り当て | すべてのスレッドには名前のないデータ スロットが割り当てられます。パフォーマンスを向上させるには、ThreadStaticAttribute 属性でマークされたフィールドを使用します。 |
名前付きデータスロットの割り当て | 名前付きデータ スロットをすべてのスレッドに割り当てます。パフォーマンスを向上させるには、ThreadStaticAttribute 属性でマークされたフィールドを使用します。 |
クリティカル領域の開始 | スレッドの中止または未処理の例外の影響で他のタスクが損なわれる可能性があるコード領域に実行が進もうとしていることをホストに通知します。 |
スレッドアフィニティの開始 | 現在の物理オペレーティング システム スレッドの ID に応じて、マネージド コードが実行されようとしていることをホストに通知します。 |
クリティカル領域の終了 | スレッドの中止または未処理の例外が現在のタスクにのみ影響を与えるコード領域に実行が進もうとしていることをホストに通知します。 |
エンドスレッドアフィニティ | 現在の物理オペレーティング システム スレッドの ID に応じて、マネージド コードの実行が完了したことをホストに通知します。 |
無料の名前付きデータスロット | プロセス内のすべてのスレッドの名前とスロット間の関連付けを排除し、パフォーマンスを向上させるには、ThreadStaticAttribute 属性でマークされたフィールドを使用します。 |
データの取得 | 現在のスレッドの現在のドメイン内の現在のスレッドによって指定されたスロットから値を取得します。パフォーマンスを向上させるには、ThreadStaticAttribute 属性でマークされたフィールドを使用します。 |
ドメインの取得 | 現在のドメインで現在実行中のスレッドを返します。 |
ドメインIDの取得 | 一意のアプリケーション ドメイン識別子を返します。 |
GetNamedDataSlot | 名前付きデータ スロットを見つけます。パフォーマンスを向上させるには、ThreadStaticAttribute 属性でマークされたフィールドを使用します。 |
割り込み | WaitSleepJoin スレッド状態のスレッドを中断します。 |
参加する | 標準の COM および SendMessage の実行を継続しながら、いずれかのスレッドが終了するまで呼び出し元のスレッドをブロックします。このメソッドにはさまざまなオーバーロード形式があります。 |
メモリーバリア | 同期メモリ アクセスは次のとおりです。現在のスレッドを処理するアクセラレータは、メモリ アクセスが MemoryBarrier を呼び出してからメモリ アクセスを実行するような方法で命令を並べ替えることはできません。 |
リセット中止 | 現在のスレッドの中止要求をキャンセルします。 |
データの設定 | 指定されたタイムスロットで現在実行中のスレッドのデータと、そのスレッドの現在のドメインを設定します。パフォーマンスを向上させるために、アプリケーション ドメインにはドメインの ThreadStaticAttribute 属性があります。 |
始める | スレッドを開始します。 |
寝る | スレッドを一定期間一時停止させます。 |
スピンウェイト | パラメータで定義された反復回数だけスレッドを待機させます。 |
VolatileRead() | フィールドの値を読み取ります。最新の値は、プロセッサまたはプロセッサ キャッシュ状態番号に関係なく、コンピュータの任意のプロセッサによって書き込まれます。このメソッドにはさまざまなオーバーロード形式があります。 |
VolatileWrite() | コンピューター内のすべてのプロセッサーが認識できるフィールドに値を即座に書き込みます。このメソッドにはさまざまなオーバーロード形式があります。 |
収率 | 呼び出し元のスレッドが現在のプロセッサ上で実行できる別のスレッドを実行し、オペレーティング システムがスレッドのリダイレクトを選択します。 |
次の例は、スレッド クラスの使用法を示しています。このページには、子スレッドからのメッセージを表示するコントロール ラベルがあります。メイン プログラムからのメッセージは、response.write(50) メソッドを使用して直接表示されるため、ページの上部に表示されます。
ソースファイルは次のとおりです。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="threaddemo._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// JP" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title> 無題のページ </title> </head> <body> <form id="form1 " runat="server"> <div> <h3>スレッドの例</h3> </div> <asp:Label ID="lblmessage" runat="server" Text="Label"> </asp:Label> < /フォーム> </body> </html>
バックグラウンドコードは次のとおりです。
System.Collections を使用; System.Linq を使用; System.Web.UI.HtmlControls を使用; System.Web.UI.WebControls を使用; System.Xml.Linq を使用; System.Threading を使用class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { ThreadStart childthreat = new ThreadStart(childthreadcall); Response.Write("子スレッドが開始されました<br/>"); Thread(childthreat); child.Start(); Response.Write("メインは 2 秒間スリープしています....<br/>"); Thread.Sleep(2000); Response.Write("<br/>メイン中止子スレッド<br/>"); child.Abort(); } public void childthreadcall() { try{ lblmessage.Text = "<br/> >子スレッドが開始されました<br/>"; lblmessage.Text += "子スレッド: 10 まで数えます"; for( int i =0; i<10; i++) { Thread.Sleep(500); lblmessage.Text += "<br/> 子スレッド </br>" } lblmessage.Text += "<br/> 子スレッドが終了しました"; catch(ThreadAbortException e){ lblmessage.Text += "<br /> 子スレッド - 例外" }finally{ lblmessage.Text += "<br /> 子スレッド - 例外をキャッチできません";
ページがロードされると、childthreadcall() を参照として新しいスレッドが開始されます。メインスレッドのアクティビティは Web ページに直接表示されます。
2 番目のスレッドが実行され、メッセージが制御タグに送信されます。
メインスレッドは、子スレッドの実行中に 2000 ミリ秒スリープします。
子スレッドは、メインスレッドによって終了されるまで実行を続けます。終了すると、ThreadAbortException をスローして終了します。
制御はメインスレッドに戻ります。
プログラムが実行されると、次の情報が送信されます。