从 Thread.Sleep() 制作 Task.Delay() [重复]
Posted
技术标签:
【中文标题】从 Thread.Sleep() 制作 Task.Delay() [重复]【英文标题】:To make Task.Delay() from Thread.Sleep() [duplicate] 【发布时间】:2017-11-09 16:06:19 【问题描述】:我可以假设doTask
和doTask2
做同样的工作并且可能在代码中被替换吗?
public async static void doTask()
await Task.Delay(TimeSpan.FromSeconds(5));
public async static void doTask2()
await Task.Factory.StartNew(() =>
Thread.Sleep(TimeSpan.FromSeconds(5));
);
根据我的实验,这两个函数的作用相同。
【问题讨论】:
第一个允许为任务服务的线程返回操作系统。第二个阻塞线程。第一个更好。 其实真的different 顺便说一句,async void
considered harmful。即使在示例中也要避免。
【参考方案1】:
它们之间的一个非常非常重要的区别是Thread.Sleep()
在一段时间内阻塞线程,这意味着线程将无法用于线程池,而Task.Delay()
创建一个任务并立即释放线程,以便其他任务可以使用那个线程。
Thread.Sleep
可能很容易导致线程饥饿。
为了演示(注意我已将返回类型更改为Task
):
static void Main(string[] args)
Task.WaitAll(Enumerable.Range(0, 1000).Select(o => doTask()).ToArray());
Console.WriteLine("1");
Task.WaitAll(Enumerable.Range(0, 1000).Select(o => doTask2()).ToArray());
Console.WriteLine("2");
public async static Task doTask() => await Task.Delay(TimeSpan.FromSeconds(1));
public async static Task doTask2() => await Task.Factory.StartNew(() => Thread.Sleep(TimeSpan.FromSeconds(1)));
您会很快看到1
,但要出现2
需要很多时间(在我的 8 核 CPU 上需要几分钟)。
经验法则:使用线程 - 使用 Thread.Sleep
,使用任务 - 坚持使用 Task.Delay
。
【讨论】:
添加到此线程切换和 CPU 缓存失效 - 如果该方法确实有用,Sleep()
将强制线程切换并从线程数据中清空 CPU 缓存
以上是关于从 Thread.Sleep() 制作 Task.Delay() [重复]的主要内容,如果未能解决你的问题,请参考以下文章
C#中的Task.Delay()和Thread.Sleep()区别
如果 Task.Delay 优于 Thread.Sleep,为啥本书中的示例使用 Thread.Sleep?
Thread.Sleep(2500) 与 Task.Delay(2500).Wait()
我是不是应该始终使用 Task.Delay 而不是 Thread.Sleep? [复制]