C# 从Thread.Sleep()生成Task.Delay()
我可以假设C# 从Thread.Sleep()生成Task.Delay(),c#,multithreading,C#,Multithreading,我可以假设doTask和doTask2做相同的工作,并且可能在代码中被替换吗 public async static void doTask() { await Task.Delay(TimeSpan.FromSeconds(5)); } public async static void doTask2() { await Task.Factory.StartNew(() => {
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));
});
}
根据我的实验,这两个函数的作用是相同的。它们之间一个非常重要的区别是
Thread.Sleep()
在一段时间内阻塞线程,这意味着线程池将无法使用线程,而Task.Delay()
创建一个任务并立即释放线程,以便其他任务可以使用该线程
线程。睡眠
很容易导致线程不足
要演示(请注意,我已将返回类型更改为Task
):
您将很快看到1
,但是2
的出现需要很多时间(在我的8核CPU上需要几分钟)
拇指规则:使用线程-使用
Thread.Sleep
,使用任务-坚持执行Task.Delay
第一个规则允许为任务提供服务的线程返回操作系统。第二个阻塞线程。第一个更好。其实真的是一个旁白。即使在示例中也要避免这种情况。除了线程切换和CPU缓存失效之外,如果该方法做了有用的工作,Sleep()
将强制执行线程切换并从线程数据中清空CPU缓存
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)));