Task.Delay().Wait()
的时间要比 Thread.Sleep()
要长4倍?例如:task-00 运行在 只有线程9 上,并花费了 2193ms。
我知道,在任务中进行同步等待是不好的,因为整个线程被阻塞。这只是一个测试。
在控制台应用程序中进行简单测试:
bool flag = true;
var sw = Stopwatch.StartNew();
for (int i = 0; i < 10; i++)
{
var cntr = i;
{
var start = sw.ElapsedMilliseconds;
var wait = flag ? 100 : 300;
flag = !flag;
Task.Run(() =>
{
Console.WriteLine($"task-{cntr.ToString("00")} \t ThrID: {Thread.CurrentThread.ManagedThreadId.ToString("00")},\t Wait={wait}ms, \t START: {start}ms");
//Thread.Sleep(wait);
Task.Delay(wait).Wait();
Console.WriteLine($"task-{cntr.ToString("00")} \t ThrID: {Thread.CurrentThread.ManagedThreadId.ToString("00")},\t Wait={wait}ms, \t END: {sw.ElapsedMilliseconds}ms");
;
});
}
}
Console.ReadKey();
return;
使用 Task.Delay().Wait()
:
任务-03 线程ID: 05, 等待时间=300毫秒, 开始时间: 184毫秒
任务-04 线程ID: 07, 等待时间=100毫秒, 开始时间: 184毫秒
任务-00 线程ID: 09, 等待时间=100毫秒, 开始时间: 0毫秒
任务-06 线程ID: 04, 等待时间=100毫秒, 开始时间: 185毫秒
任务-01 线程ID: 08, 等待时间=300毫秒, 开始时间: 183毫秒
任务-05 线程ID: 03, 等待时间=300毫秒, 开始时间: 185毫秒
任务-02 线程ID: 06, 等待时间=100毫秒, 开始时间: 184毫秒
任务-07 线程ID: 10, 等待时间=300毫秒, 开始时间: 209毫秒
任务-07 线程ID: 10, 等待时间=300毫秒, 结束时间: 1189毫秒
任务-08 线程ID: 12, 等待时间=100毫秒, 开始时间: 226毫秒
任务-09 线程ID: 10, 等待时间=300毫秒, 开始时间: 226毫秒
任务-09 线程ID: 10, 等待时间=300毫秒, 结束时间: 2192毫秒
任务-06 线程ID: 04, 等待时间=100毫秒, 结束时间: 2193毫秒
任务-08 线程ID: 12, 等待时间=100毫秒, 结束时间: 2194毫秒
任务-05 线程ID: 03, 等待时间=300毫秒, 结束时间: 2193毫秒
任务-03 线程ID: 05, 等待时间=300毫秒, 结束时间: 2193毫秒
任务-00 线程ID: 09, 等待时间=100毫秒, 结束时间: 2193毫秒
任务-02 线程ID: 06, 等待时间=100毫秒, 结束时间: 2193毫秒
任务-04 线程ID: 07, 等待时间=100毫秒, 结束时间: 2193毫秒
任务-01 线程ID: 08, 等待时间=300毫秒, 结束时间: 2193毫秒
Thread.Sleep()
:任务-00 ThrID:03,等待= 100ms,开始:0ms
任务-03 ThrID:09,等待= 300ms,开始:179ms
任务-02 ThrID:06,等待= 100ms,开始:178ms
任务-04 ThrID:08,等待= 100ms,开始:179ms
任务-05 ThrID:04,等待= 300ms,开始:179ms
任务-06 ThrID:07,等待= 100ms,开始:184ms
任务-01 ThrID:05,等待= 300ms,开始:178ms
任务-07 ThrID:10,等待= 300ms,开始:184ms
任务-00 ThrID:03,等待= 100ms,结束:284ms
任务-08 ThrID:03,等待= 100ms,开始:184ms
任务-02 ThrID:06,等待= 100ms,结束:285ms
任务-09 ThrID:06,等待= 300ms,开始:184ms
任务-04 ThrID:08,等待= 100ms,结束:286ms
任务-06 ThrID:07,等待= 100ms,结束:293ms
任务-08 ThrID:03,等待= 100ms,结束:385ms
任务-03 ThrID:09,等待= 300ms,结束:485ms
任务-05 ThrID:04,等待= 300ms,结束:486ms
任务-01 ThrID:05,等待= 300ms,结束:493ms
任务-07 ThrID:10,等待= 300ms,结束:494ms
任务-09 ThrID:06,等待= 300ms,结束:586ms
编辑:
使用
async
lambda和await
Task.Delay()
与Thread.Sleep()
一样快,甚至可能更快(511ms)。编辑2:
使用
ThreadPool.SetMinThreads(16, 16);
,Task.Delay().Wait()
在循环的10次迭代中与Thread.Sleep
一样快。如果迭代次数更多,则速度会变慢。有趣的是,如果我将Thread.Sleep
的迭代次数增加到30而没有进行调整,则仍然比使用Task.Delay().Wait()
的10次迭代更快。编辑3:
重载
Task.Delay(wait).Wait(wait)
与Thread.Sleep()
一样快。
ThreadPool.SetMinThreads(16, 16);
,您会发现它可以将执行时间缩短到您所期望的。这是因为@Damien_The_Unbeliever的已删除答案中描述的原因(即一旦超过最小线程数,线程池会将每个新线程的启动延迟2毫秒)。 - Matthew WatsonTask.Delay().Wait()
是没有意义的。Task.Delay() 会返回一个任务,该任务在 System.Threading.Timer 触发时完成。这个与 async/await 结合使用,可以延迟而不阻塞任何线程。Task.Delay().Wait()
立即阻塞线程,同时等待计时器触发,失去了Task.Delay()
提供的任何好处。 - Panagiotis KanavosTask.Delay()
的工作是不阻塞。它的工作是在计时器到期后恢复执行一个已经存在的线程池线程,而不是被阻塞。 - Panagiotis Kanavos