ホームページ >バックエンド開発 >C#.Net チュートリアル >C#Thread の少しずつの詳細な紹介

C#Thread の少しずつの詳細な紹介

黄舟
黄舟オリジナル
2017-03-20 13:17:171891ブラウズ

C#のThreadを使用して簡単なタイマーを作成しました。 45 分後に休憩できるように、45 分後に音楽プロンプトが鳴ります。

最初に使用した TimeSpan の減算方法は、Thread のスタートアップ関数内で次のように記述されました:

    public void CountTime()
    {
                
       while (true)
       {
          TimeSpan tsNew = new TimeSpan(DateTime.Now.Ticks);
          TimeSpan tsIn = tsNew - tsOld;
          if (tsIn.Minutes >= 1)
          {
        
             while (true)
             {
                 TimeSpan tsNewer = new TimeSpan(DateTime.Now.Ticks);
                 TimeSpan tsIner = tsNewer - tsNew;
                 if (tsIner.Minutes >= 10)
                 {
                    //十分钟后线程重启
                     tsOld = tsNew;
                     break;
                 }
             }
             
           }
       }
    }
後になって、この方法はあまりにも非効率であることがわかりました。もちろん、この関数を使用して CPU 使用時間を削減することもできます。実際、途中に Thread.Sleep(20) を追加すると、CPU 消費量を大幅に削減できます。その後、C# の Thread には独自の関数 join() があり、スレッドを一定時間待機させることができることがわかりました。呼び出しメソッドは以下の通りです

th.Join(new TimeSpan(hours, minutes, months)); 待機中、スレッドはWaitSleepJoin

状態になります。

もちろん、Thread.Sleep(millionseconds); を呼び出すこともできます。これが Sleep と Join の違いです

スレッドが Sleep を実行すると、システムは一定期間実行キューを終了します。終了すると、システムはクロック割り込みを生成し、それによってスレッドを実行キューに戻し、スレッドの実行を再開します。 Sleep メソッドのパラメータが 0 の場合、このスレッドは待機中の他のスレッドを実行できるように一時停止する必要があり、CPU がここで制御を再分配し、実行されたばかりのプログラムである可能性もあります。このようにすると、CPU 使用率は常に 100% になります。 インターフェースが機能しなくなっても、マウスを動かすことはできる場合があります。 Timeout.Infinite の場合、スレッドは Thread.Interrupt を呼び出す別のスレッドによって中断されるか、Thread.Abort によって中止されるまでスリープすることを意味します。
親スレッドが子スレッドより先に終了した場合、子スレッドは親スレッドの終了と同時に強制的に終了します。 Thread.Join() メソッドにより、親スレッドは子スレッドが終了するまで待機します。 Join メソッドには戻り値があり、値が true の場合、スレッドが終了したことを意味します。 false の場合、スレッドがその時間待機しても終了していないことを意味します。スレッドが Unstarted 状態にある場合、join() を呼び出すと ThreadStateException 例外が発生します。スレッドが終了している場合、この関数を呼び出すとすぐに戻り値が取得されます。

たとえば、以下のメインプログラム

...
ThreadStart st = New ThreadStart(fun);
Thread th = new Thread(ThreadStart st);
th.Start();
Application.Exit();
...
 
//下面是fun函数
void fun()
{
    while(true)
    {
            ...
    }
}

このプログラムの唯一の問題は、メインプログラムが終了した後にスレーブスレッドが終了していない可能性があることです。 (このスレーブスレッドが可哀想ですね…)

ちなみにスレッドのステータスをいくつか挙げておきます:

作成: 新しいプロセスが作成されると、そのプロセス用のスレッドも作成されます。 。スレッドは新しいスレッドを作成することもできます。

Ready: スレッドはプロセッサを除くすべてのリソースを取得しました。

Running: スレッドはプロセッサ上で実行されています。

ブロック中:

イベントを待機しているため、スレッドが一時停止されています。

終了: スレッドが完了しました。

しかし、C# スレッドにはさらにいくつかの状態があります:

Aborted、AbortRequested、Background、Running、Stopped、StopRequested、Suspended、SuspendRequested、Unstarted、WaitSleepJoin。

Abort() は ThreadState.AbortRequested を引き起こします。Abort() を呼び出すスレッドが制御を獲得した後、ThreadState.Aborted が発生します。AbortRequested と Aborted の違いは、一方が停止するか、もう一方が停止しないことです。停止とは、スレッドが終了したことを意味します。ただし、何度も試してみたところ、Abort() 関数が呼び出されると、スレッドのステータスが停止に変わることがわかりました。 Aborted 状態に変更する方法はまだ検討中です。他の州も同様です。対応する関数を呼び出すと対応するステータス要求が生成され、対応するステータスを取得するまでに時間がかかります。 Unstarted は Start() 関数が呼び出されておらず、Running は Start() 関数または Resume() 関数を呼び出した結果です。 WaitSleepJoin は I/O を待機しているか、Join() メソッドを呼び出しています。

ここでの Join() メソッドと Sleep() メソッドの違いは、Join() のスレッド状態が WaitSleepJoin に入るために呼び出されるかどうか、および Sleep() のスレッド状態が呼び出されるか Running になるかどうかにあります。

スレッドを一時停止するメソッドは Suspend() です。このメソッドを呼び出した後、スレッドは SuspendRequest 状態になります。 Suspended() が呼び出された後もスレッドが join() メソッドを実行している場合、Suspended() ではスレッドを一時停止する前にスレッドが safe ポイントに到達する必要があるため、スレッドのステータスは SuspendRequested|WaitSleepJoin になります。しかし、ここの結合の時計はまだカウント中です。したがって、結合カウントを一時停止するためにどのような方法を使用すればよいのかはまだわかりません。もちろん、結合を使用せずにスレッドを完全に一時停止するという問題も解決できます。スレッドがまだ実行されているため、どの Suspended() 関数が何をしているのかわかりません。また、Suspend() と、Suspend() の呼び出し後にスレッドを再度再開できるようにする Resume() メソッドの使用が非推奨になったことにも言及する価値があります。 理由は簡単で、これらの 2 つのメソッドは他のスレッドによって実行され、他のスレッドは Suspend() されているスレッドの状態 (特定のクラスのコンストラクターの実行期間や破壊など) を正確に知ることができないためです。 。したがって、この関数を同期に使用するのは危険です。

なお、Thread.Sleep(n)のnは正確に時間を制御できないことに注意してください。スレッド化にどれくらい時間がかかるかを考えると、このコントロールには問題があります。現在のスレッドがフォアグラウンド スレッドの場合、スレッドを終了するには、Thread.Sleep(n) が n より大きくなければなりません。バックグラウンド プロセスの場合、メイン プログラムが終了すると、このスレッドは起動できなくなります...悲惨です...そのため、通常は Thread.Sleep() 関数を使用しないことをお勧めします。さらに、Sleep 機能は同期には使用できません。Peter 氏は、プログラムの Sleep 機能は非常に悪い設計であると述べました。


以上がC#Thread の少しずつの詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。