Threadクラスでは処理の優先度を変更したり、アプリケーションの終了に伴い途中で終了されてしまうのを防ぐことができます。
既定ではフォアグラウンド スレッドで実行され、アプリケーションを終了してもスレッドは終了しません。
public Thread (System.Threading.ThreadStart start);
このスレッドが実行を開始するときに呼び出されるメソッドを表すデリゲートを、startで指定します。スレッドにオブジェクトを渡すならば、次の形式を用います。
public Thread(System.Threading.ParameterizedThreadStart start)Thread(ParameterizedThreadStart) - Thread コンストラクター (System.Threading) | Microsoft Learn
スレッドで実行するメソッドはParameterizedThreadStartデリゲート型ですが、その形式はWaitCallbackデリゲートと同一です。ParameterizedThreadStart デリゲート (System.Threading) | MSDN
型 | プロパティ | 内容 |
---|---|---|
Thread | CurrentThread | 現在実行中のスレッド |
Context | CurrentContext | スレッドが実行されている現在のコンテキスト (.NET Core以降、非対応) |
型 | プロパティ | 内容 |
---|---|---|
string | Name | スレッドの名前 |
bool | IsAlive | trueならば、スレッドは起動しており、正常終了も中止もされていない。より詳細な情報はThreadStateで確認できる |
bool | IsBackground | trueならば、バックグラウンド スレッド。ThreadState.HasFlag(ThreadState.Background) としても確認できる
Thread.CurrentThread.IsBackground = falseとして、現在のスレッドをフォアグラウンドに変更すべきではない。その必要があるならば、新規にThreadを作成する c# - Thread Pool and .IsBackground in .NET - Stack Overflow |
bool | IsThreadPoolThread | trueならば、マネージド スレッドプールに所属 |
ThreadState | ThreadState | スレッドの状態 (ビットの組み合わせで表現される)。これはデバッグ用であり、スレッドの同期に用いてはならない Remarks |
ThreadPriority | Priority | スケジューリング優先度。ただし、OSがこれに従う保証はない |
int | ManagedThreadId | プロセス内で一意なスレッドの識別子。これはスレッド ウィンドウのマネージドIDと一致する |
CultureInfo | CurrentCulture | 現在のスレッドのカルチャ。
現在のスレッド以外で使用したときは確実に機能しない。よってCultureInfo.CurrentCultureを用いる Remarks - Thread.CurrentCulture Property (System.Threading) | Microsoft Learn |
CultureInfo | CurrentUICulture | |
このプロパティには一度しか設定できません。null以外に設定された状態で再設定しようとすると、「このプロパティは既に設定されているため、変更できません。」としてInvalidOperationExceptionが投げられます。 Remarks - Thread.Name Property (System.Threading) | Microsoft Learn Name - thread.cs
列挙子 | 状態 | |
---|---|---|
Running | 0 | 開始していて、まだ停止していない |
StopRequested | 1 | 停止が要求されている |
SuspendRequested | 2 | 中断が要求されている |
Background | 4 | バックグラウンド スレッドで実行中 |
Unstarted | 8 | まだStart()が呼ばれていない |
Stopped | 16 | 停止している |
WaitSleepJoin | 32 | ブロックされている |
Suspended | 64 | 中断している |
AbortRequested | 128 | Abort(Object)が呼ばれているが、まだThreadAbortExceptionを受け取っていない |
Aborted | 256 | 停止しているが、まだ状態がStoppedに変化していない |
状態は次のように変化します。
Thread thread = null; ThreadState state; // Running thread = new Thread(() => { state = thread.ThreadState; // Running }); state = thread.ThreadState; // Unstarted thread.Start(); state = thread.ThreadState; // Running thread.Join(); state = thread.ThreadState; // Stopped
メソッド | |
---|---|
Start() | ThreadStateをRunningに変更する |
Abort() | ThreadAbortException例外を発生させ、スレッドを終了させる |
Interrupt() | ThreadStateがWaitSleepJoinであるスレッドを中断させる |
Join() | スレッドが終了するまで、呼び出し元のスレッドをブロックする |
SetData(LocalDataStoreSlot, Object) | 現在のスレッドの指定のスロットに、値を設定できる |
GetData(LocalDataStoreSlot) | 現在のスレッドの指定のスロットから、値を取得できる |
SetApartmentState(ApartmentState) | アパートメント状態を設定できる |
GetApartmentState() | アパートメント状態を取得できる |
スレッドは、Start()メソッドの呼び出しにより開始できます。
public void Start( object parameter )Thread.Start メソッド (Object) (System.Threading) | MSDN
Start()で開始したスレッドは、終了した後でもStart()で再開させることはできません。その必要があるならば、あらためてThreadのインスタンスを生成し、それをStart()で開始させます。 Remarks - Thread.Start Method (System.Threading) | MSDN Remarks - ThreadStateException Class (System.Threading) | MSDN
void Main() { Thread thread = new Thread(Method); // スレッドを起動する thread.Start(123); } void Method( Object param ) { // このメソッドが制御を戻すと、スレッドは破棄される }
ラムダ式では次のように記述できます。
new Thread( param =>
{
// 別スレッドでの処理
}).Start(123);
スレッドへはStart()の引数で値を渡せますが、スレッドから値を戻す方法は提供されていません。よって必要ならばスレッドの開始前にローカルに変数を定義しておき、スレッド内でその変数へ書き込むようにします。c# - Returning a value from thread? - Stack Overflow
int result; Thread thread = new Thread(param => { result = (int)param * 2; }); thread.Start(10); thread.Join();
Abort()でスレッドを強制的に終了させる方法は推奨されず、可能ならばCancellationTokenSourceを用います。それにはStart()の引数で、それのCancellationTokenを渡します。 スレッドの破棄 | Microsoft Learn マネージド スレッドのキャンセル - .NET | Microsoft Learn
現在のスレッドを中断させられます。
public static void Sleep(
int millisecondsTimeout // スレッドを中断する時間 [msec]
)
Thread.Sleep メソッド (System.Threading) | MSDN
millisecondsTimeoutの時間、現在のスレッドを一時停止させられます。これは静的メソッドのため、メインスレッドからも直接呼び出せます。
なお.NET Framework 4.5以降ならば、Task.Delay()を用いることで現在のスレッドを他の処理に割り当てられます。
await Task.Delay(1000);