C#のTask.Delay()とThread.Sleep()
2022-02-08 18:27:13
- Thread.Sleep()は同期遅延、Task.Delay()は非同期遅延です。
- Thread.Sleep()はスレッドをブロックし、Task.Delay()はブロックしない。
- Thread.Sleep()はキャンセルできませんが、Task.Delay()はキャンセル可能です。
- Task.Delay()は、基本的に与えられた時間だけ実行するタスクを作成し、Thread.Sleep()は現在のスレッドを与えられた時間だけスリープさせます。
- Task.Delay()をデコンパイルします。基本的にタイマーをタスクで包んだものです。
- Task.Delay()とThread.Sleep()の最大の違いは、Task.Delay()は非同期で実行することを目的としていることです。同期コードでTask.Delay()を使っても意味がありませんし、非同期コードでThread.Sleep()を使っても非常に悪いアイディアにしかなりません。Task.Delay()は通常、awaitキーワードで呼び出します。
- 私の理解では Task.Delay()、async/await、CancellationTokenSource を組み合わせて使用すると、非同期の遅延を制御することができます。
参考にしてください。
https://www.cnblogs.com/yy1234/p/8073732.html
https://blog.csdn.net/shu19880720/article/details/72901876
https://code.msdn.microsoft.com/ThreadSleep-vs-TaskDelay-766b46b7/view/Discussions#content
https://blog.csdn.net/wushang923/article/details/41015063
http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspx (コメント欄で物議をかもす)
https://oomake.com/question/5779232
https://walterlv.com/post/sleep-delay-zero-vs-yield.html
以下は、デバッグ時の私のコードです。
コード1
using System;
Threading;
Tasks;
namespace Delay_And_Sleep
Tasks; namespace Delay_And_Sleep
class Program
program
static void Main(string[] args)
StartNew(delegate) {
Factory.StartNew(delegate
StartNew(delegate) {
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ****** StartSleep()");
for (int i = 1; i < 20; i++)
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff") + " ***Sleep*** " + i);
Thread.Sleep(100);
}
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff") + " ****** EndSleep()");
});
Task.Factory.StartNew(() =>
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ====== Start Delay()");
for (int i = 101; i < 120; i++)
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ===Delay=== " + i);
Task.Delay(100);//needs .net4.5 and above
}
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ====== End Delay()");
});
//ToString("yyyy-MM-dd HH:mm:ss.ffff") + "press enter to close . . . ");
Console.ReadLine();
}
}
}
実行結果を表示します。
コード2
using System;
Tasks;
namespace Delay_async_await
Tasks; namespace
class Program
Tasks; namespace Delay_async_await { class Program
// This code implements "synchronous" Delay by async/awatit
static void Main(string[] args)
{
Factory.StartNew(async () =>
StartNew(async () => {
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ====== StartDelay()");
for (int i = 101; i < 120; i++)
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ===Delay=== " + i);
await Task.Delay(100);//requires .net4.5 and above
}
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ====== End Delay()");
});
//ToString("yyyy-MM-dd HH:mm:ss.ffff") + "press enter to close . . . ");
Console.ReadLine();
}
}
}
実行結果。
コード3
using System;
Generic;
ComponentModel;
Data;
Data; using System;
Data; using System;
Text; using System;
Threading;
Tasks;
Tasks; using System;
namespace CancelDelay
Forms; namespace Cancel Delay
public partial class Form1 : Form
{
CancellationTokenSource cts = new CancellationTokenSource();
public Form1()
{
InitializeComponent();
}
void PutThreadSleep()
{
Thread.Sleep(5000);
}
async Task PutTaskDelay()
{
try
{
await Task.Delay(5000, cts.Token);// requires .
Net4.5 support required }
catch (TaskCanceledException ex)
{
MessageBox.Show(ex.ToString());
}
}
private void btnThreadSleep_Click(object sender, EventArgs e)
{
PutThreadSleep();
MessageBox.Show("Sleep : I am back");
}
// use async/await to observe the effect; if not, just pop up the MessageBox
private async void btnTaskDelay_Click(object sender, EventArgs e)
{
await PutTaskDelay();
MessageBox.Show("Delay : I am back");
}
private void btnCancelTaskDelay_Click(object sender, EventArgs e)
{
cts.Cancel();
}
}
}
実行結果。
関連
-
! 拒否]マスター->マスター(フェッチファースト)問題の解決法
-
github共通の操作と共通のエラー! fatal: リモートリポジトリから読み取れませんでした。
-
eclipse left パッケージエクスプローラーのフォントサイズ設定
-
MySql ERROR 1046(3D000): 選択されたデータベースがない場合の解決策
-
Bluetooth接続のタイムアウト現象
-
自動配線された依存関係のインジェクションに失敗した 解決方法
-
merge into は、あるテーブルの 1 つの列から別のテーブルの列にデータをコピーします。
-
宣言されたパッケージが Solution と一致しない
-
STM32 学習 0 未定義識別子 "..." 使用時のエラー 解決方法
-
json文字列のダブルクォートが&quotになるのですが、どうすれば解決できますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
"Undefined symbols for architecture x86_64:" エラーを解決しました。
-
要素 popover がクリックされると表示されない 問題が報告される 未定義のプロパティ '$refs' を読み取ることができない
-
com.android.tools.build:gradle:3.3.1 が見つかりませんでした。
-
C++ ベクトル検索エラー: 'find(std::vector<int>::iterator, std::v)' の呼び出しにマッチする関数がありません。
-
AS ERROR: x86 エミュレーションは現在ハードウェアアクセラレーションが必要です!
-
[エラー] '{' トークンの前に期待される式
-
ArrayAdapter は、リソース ID が TextView である必要があります。
-
ModuleNotFoundError を解決する。Pythonに'tensorflow._api'という名前のモジュールはありません。
-
std::invalid_argument' what() のインスタンスを投げた後に呼び出された処理を終了させる: stoi
-
Pythonです。TypeError: 'dict' オブジェクトは呼び出し可能ではありません。