C# の Thread.Sleep()
-
C#
でthread.sleep()
が有害である理由 -
C#
でのthread.sleep()
のしくみ - 非同期プログラミング
-
2つのメソッドを同時に実行する(C# の
async
およびawait
キーワード)
このガイドでは、C# での thread.sleep()
の使用が有害であると見なされる理由と、この特定のアプローチを使用すべきでない理由を学習します。
thread.sleep()
を使用するとどうなりますか?別のアプローチはありますか?
このガイドですべてを見つけてください。飛び込みましょう。
C#
で thread.sleep()
が有害である理由
thread.sleep()
が有害である理由を理解するには、このメソッドの背後にある作業を理解する必要があります。さて、C# では、sleep
メソッドが使用されます。
これを使用して、現在の機能(スレッド実行)を特定の期間一時停止または一時停止できます。時間をミリ秒単位で渡して、スレッドの実行をしばらく中断することができます。
以下のコードに示すように、TimeSpan
プロパティを使用することもできます。
// Time in milliseconds
Thread.Sleep(5000);
Or
// Time in hours, minutes, seconds
TimeSpan tsObj = new TimeSpan(0, 0, 5);
Thread.Sleep(tsObj);
これで、上記の両方のアプローチでプログラムが 5 秒間停止します。これは、上記のコードを通じて、スレッドを 1 秒間中断しようとしていることを意味します。
しかし、これはどういう意味ですか?それの働きを理解しましょう。
C#
での thread.sleep()
のしくみ
プログラムが行単位で実行されることは誰もが知っています。つまり、プログラム全体が次々と同期して実行されます。プログラミング中に、完了するまでに時間がかかるタスクを実行する必要がある場合があります。
たとえば、API からデータをフェッチする場合、sleep
関数を使用して待機させ、API からそのデータを取得し、後でプログラムの残りの部分を実行できます。これは必要ですが、非常に有害で貧弱なアプローチです。
たとえば、フェッチしようとしているデータは大きく、時間がかかる可能性があります。その間、プログラムは停止されます。それは理想的なアプローチではありません。
Thread.Sleep(n)
は、実行中のスレッドを n
ミリ秒以内にできるだけ多くのタイムスライス(スレッドクォンタムとも呼ばれます)停止することを意味します。タイムスライスの期間は、Windows のバージョン/タイプと使用するプロセッサによって異なりますが、通常は 15〜30 ミリ秒続きます。
これは、スレッドが n
ミリ秒より長くブロックされる可能性が高いことを示しています。スレッドが正確に n
ミリ秒後に再起動する可能性はほとんどありません。
したがって、Thread.Sleep
はタイミングの目的を果たしません。
スレッドは有限のリソースであり、約 200,000 サイクルの作成と 100,000 サイクルの破棄が必要です。デフォルトでは、コンテキスト遷移ごとに 2,000〜8,000 サイクルを使用し、スタック用に 1 メガバイトの仮想メモリを予約します。
代替アプローチとは何ですか
プログラムを完全に実行するには、スレッドを遅らせる必要がある場合があります。前述のように、API データをフェッチする必要がある場合がありますが、これには時間がかかります。
しかし、それが原因でプログラム全体を停止することは悪いアプローチです。では、どうすればそれを回避できますか?
非同期プログラミングを紹介しましょう。
非同期プログラミング
C# の async
および await
キーワードは、非同期プログラミングを最近非常に一般的にするのに役立ちます。UI を操作するときは、アプリケーション全体が操作の完了を待機し、巨大なファイルの読み取りやボタンのクリックなど、長時間かかるメソッドを使用する必要があります。
つまり、同期アプリケーションのいずれかのプロセスがブロックされると、アプリケーション全体も停止し、タスク全体が完了するまでアプリケーションは機能しなくなります。
このような状況では、非同期プログラミングが非常に役立ちます。アプリケーションは、非同期プログラミングを採用することにより、完了に依存しないタスクを続行できます。
async
および await
キーワードを使用すると、従来の非同期プログラミングのすべての利点をはるかに少ない作業で実現できます。
2つのメソッドを同時に実行する(C# の async
および await
キーワード)
たとえば、FirstMethod()
と SecondMethod()
の 2つのメソッドがあり、これらは互いに独立しており、FirstMethod()
はそのタスクを実行するのに長い時間がかかります。
同期プログラミングは FirstMethod()
で始まり、それが終了するのを待ってから SecondMethod()
に移り、実行されます。両方の手順が独立している場合でも、プロセスには多くの時間がかかります。
単純なスレッドプログラミングを利用することですべての機能を同時に実行できますが、タスクが終了するのを待つ間、ユーザーインターフェイスがブロックされます。従来のプログラミングでは、この問題を解決するために多くのコードを記述する必要がありましたが、async
および await
キーワードを使用すると、はるかに少ないコードで問題を解決できます。
他の例も見ていきます。そのような場合、SecondMethod()
が FirstMethod()
に依存している場合、await
キーワードを使用して FirstMethod()
の実行が終了するのを待ちます。
C# では、async
と await
は、タスクが完了したときにコントロールが戻る場所を示すコードマーカーです。
実際の例から始めると、その背後にあるプログラミングをよりよく理解するのに役立ちます。次のコードを見てください。
class Program {
static void Main(string[] args) {
FirstMethod();
SecondMethod();
Console.ReadKey();
}
public static async Task FirstMethod() {
await Task.Run(() => {
for (int i = 0; i < 100; i++) {
Console.WriteLine(" First Method");
// Do something
Task.Delay(100).Wait();
}
});
}
public static void SecondMethod() {
for (int i = 0; i < 25; i++) {
Console.WriteLine(" Second Method ");
// Do something
Task.Delay(100).Wait();
}
}
}
上記のコードの出力は次のようになります。
First Method
Second Method
Second Method
First Method
Second Method
First Method
Second Method
First Method
Second Method
First Method
Second Method
First Method
Second Method
First Method
Second Method
Second Method
First Method
Second Method
First Method
Second Method
First Method
Second Method
First Method
Second Method
First Method
Second Method
Second Method
Second Method
Second Method
Second Method
上記のコードでわかるように、1つのスレッドの実行を停止する必要があるという理由だけで、プログラム全体が停止するわけではありません。これらは両方とも、非同期プログラミングを使用して同時に実行できます。
ある時点で API データをフェッチする必要があるとしましょう。これには時間がかかります。したがって、プログラムはデータを取得せずに次の行に移動するので、そのデータを取得するために少し遅らせてから、次の行に移動する必要があります。
Haider specializes in technical writing. He has a solid background in computer science that allows him to create engaging, original, and compelling technical tutorials. In his free time, he enjoys adding new skills to his repertoire and watching Netflix.
LinkedIn