C#中的Task.Delay()和Thread.Sleep()區(qū)別(代碼案例)
一、簡(jiǎn)介
1.Thread.Sleep()是同步延遲,Task.Delay()是異步延遲。
2.Thread.Sleep()會(huì)阻塞線(xiàn)程,Task.Delay()不會(huì)。
3.Thread.Sleep()不能取消,Task.Delay()可以。
4.Task.Delay()實(shí)質(zhì)創(chuàng)建一個(gè)運(yùn)行給定時(shí)間的任務(wù),Thread.Sleep()使當(dāng)前線(xiàn)程休眠給定時(shí)間。
5.反編譯Task.Delay(),基本上講它就是個(gè)包裹在任務(wù)中的定時(shí)器。
6.Task.Delay()和Thread.Sleep()最大的區(qū)別是Task.Delay()旨在異步運(yùn)行,在同步代碼中使用Task.Delay()是沒(méi)有意義的;在異步代碼中使用Thread.Sleep()是一個(gè)非常糟糕的主意。通常使用await關(guān)鍵字調(diào)用Task.Delay()。
二、代碼案例
案例一:Thread.Sleep()和Task.Delay()比較
代碼:
static void Main(string[] args)
{
//阻塞,出現(xiàn)CPU等待...
Task.Factory.StartNew(delegate
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ****** Start Sleep()******");
for (int i = 1; i <=10; i++)
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "******Sleep******==>" + i);
Thread.Sleep(1000);//同步延遲,阻塞一秒
}
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ******End Sleep()******");
Console.WriteLine();
});
//不阻塞
Task.Factory.StartNew(() =>
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ======StartDelay()======");
for (int i =1; i <=10; i++)
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ======Delay====== ==>" + i);
Task.Delay(1000);//異步延遲
}
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ======End Delay()======");
Console.WriteLine();
});
Console.ReadLine();
Console.ReadKey();
}
結(jié)果:
通過(guò)運(yùn)行結(jié)果截圖對(duì)比看出,Thread.Sleep()是同步延遲,Task.Delay()是異步延遲。

案例二:通過(guò)async/await實(shí)現(xiàn)Task.Delay()同步
代碼:
//該段代碼通過(guò)async/awatit實(shí)現(xiàn)“同步”Delay
static void Main(string[] args)
{
Task.Factory.StartNew(async () =>
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ======Start Delay()======");
for (int i = 1; i <=10; i++)
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ======Delay======" + i);
await Task.Delay(1000);
}
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " ======End Delay()======");
});
Console.ReadKey();
}
結(jié)果:
運(yùn)行結(jié)果可以看出,通過(guò)async/await實(shí)現(xiàn)了Task.Delay()同步

案例三:Task.Delay()取消
代碼:
class Program
{
#region
CancellationTokenSource cts = new CancellationTokenSource();
void PutThreadSleep()
{
Thread.Sleep(5000);
}
async Task PutTaskDelay()
{
try
{
await Task.Delay(5000, cts.Token);//需要.net4.5的支持
}
catch (TaskCanceledException ex)
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff ==>") + ex.ToString());
}
}
private void ThreadSleep()
{
PutThreadSleep();
Console.WriteLine("Sleep : I am back");
}
private async void TaskDelay()
{
await PutTaskDelay();
Console.WriteLine("Delay : I am back");
}
private void CancelTaskDelay()
{
cts.Cancel();
}
#endregion
static void Main(string[] args)
{
#region
Program p = new Program();
//不可取消
p.ThreadSleep();
//可取消
p.TaskDelay();
p.CancelTaskDelay();
#endregion
Console.ReadKey();
}
}
結(jié)果:
Task.Delay()取消,拋出異常信息。

三、總結(jié)
Task.Delay(),async/await和CancellationTokenSource組合起來(lái)使用可以實(shí)現(xiàn)可控制的異步延遲。
以上就是C#中的Task.Delay()和Thread.Sleep()區(qū)別(代碼案例)的詳細(xì)內(nèi)容,更多關(guān)于C# Task.Delay()和Thread.Sleep()的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#通過(guò)System.CommandLine快速生成支持命令行的應(yīng)用程序
這篇文章介紹了C#通過(guò)System.CommandLine快速生成支持命令行應(yīng)用程序的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
C#實(shí)現(xiàn)向多線(xiàn)程傳參的三種方式實(shí)例分析
這篇文章主要介紹了C#實(shí)現(xiàn)向多線(xiàn)程傳參的三種方式,以實(shí)例形式較為詳細(xì)的分析了C#多線(xiàn)程及參數(shù)傳遞的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
ListView用法中與滾動(dòng)相關(guān)的需求實(shí)現(xiàn)
這篇文章主要介紹了ListView用法中與滾動(dòng)相關(guān)的需求實(shí)現(xiàn),獲取并設(shè)置ListView的滾動(dòng)位置,以及獲取滾動(dòng)位置處的項(xiàng)目,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
C#使用SQLDMO操作數(shù)據(jù)庫(kù)的方法
這篇文章主要介紹了C#使用SQLDMO操作數(shù)據(jù)庫(kù)的方法,實(shí)例分析了基于SQLDMO.dll動(dòng)態(tài)鏈接庫(kù)操作數(shù)據(jù)庫(kù)的相關(guān)技巧,需要的朋友可以參考下2015-06-06
C#中正則表達(dá)式(Regex)過(guò)濾內(nèi)容的基本使用方法
在 Regex 類(lèi)中提供了很多方法來(lái)操作正則表達(dá)式,這篇文章主要給大家介紹了關(guān)于C#中正則表達(dá)式(Regex)過(guò)濾內(nèi)容的基本使用方法,需要的朋友可以參考下2022-08-08
c#不使用windows api函數(shù)打開(kāi)我的電腦和獲取電腦驅(qū)動(dòng)器信息
這篇文章主要介紹了c#不使用windows api函數(shù)打開(kāi)我的電腦和電腦驅(qū)動(dòng)器信息的方法,大家參考使用2013-12-12
C#實(shí)現(xiàn)兩個(gè)exe程序之間通信詳解
這篇文章主要為大家詳細(xì)介紹了C#如何使用SendMessage實(shí)現(xiàn)兩個(gè)程序之間的通信功能,文中的示例代碼簡(jiǎn)潔易懂,需要的小伙伴可以參考下2023-07-07

