Tom*_* K. 343 c# multithreading task-parallel-library
什么时候使用Task.Delay和Thread.Sleep有很好的规则?
Ste*_*ary 341
使用Thread.Sleep
时要阻止当前线程.
Task.Delay
在不阻塞当前线程的情况下使用逻辑延迟.
效率不应成为这些方法的首要考虑因素.它们的主要实际用途是作为I/O操作的重试计时器,其大小为秒而不是毫秒.
Dor*_*rus 216
最大的区别Task.Delay
和Thread.Sleep
是Task.Delay
旨在异步运行.Task.Delay
在同步代码中使用没有意义.Thread.Sleep
在异步代码中使用是一个非常糟糕的主意.
通常您会Task.Delay()
使用await
关键字调用:
await Task.Delay(5000);
Run Code Online (Sandbox Code Playgroud)
或者,如果您想在延迟之前运行一些代码:
var sw = new Stopwatch();
sw.Start();
Task delay = Task.Delay(5000);
Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
await delay;
Run Code Online (Sandbox Code Playgroud)
猜猜这会印刷什么?运行0.0070048秒.如果我们移动await delay
上面的Console.WriteLine
代替,它将打印运行5.0020168秒.
让我们来看看与以下区别Thread.Sleep
:
class Program
{
static void Main(string[] args)
{
Task delay = asyncTask();
syncCode();
delay.Wait();
Console.ReadLine();
}
static async Task asyncTask()
{
var sw = new Stopwatch();
sw.Start();
Console.WriteLine("async: Starting");
Task delay = Task.Delay(5000);
Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
await delay;
Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
Console.WriteLine("async: Done");
}
static void syncCode()
{
var sw = new Stopwatch();
sw.Start();
Console.WriteLine("sync: Starting");
Thread.Sleep(5000);
Console.WriteLine("sync: Running for {0} seconds", sw.Elapsed.TotalSeconds);
Console.WriteLine("sync: Done");
}
}
Run Code Online (Sandbox Code Playgroud)
试着预测这会印刷什么......
async:启动
异步:运行0.0070048秒
同步:启动
异步:运行5.0119008秒
异步:完成
同步:运行5.0020168秒
同步:完成
此外,有趣的是注意到Thread.Sleep
更准确,ms精度并不是真正的问题,而Task.Delay
最小可能需要15-30ms.两个函数的开销与它们具有的ms精度相比是最小的(Stopwatch
如果您需要更精确的东西,请使用Class).Thread.Sleep
仍然束缚你的线程,Task.Delay
在你等待时释放它做其他工作.
Bal*_*kas 26
如果当前线程被杀死并且您Thread.Sleep
正在执行它并且它正在执行那么您可能会得到一个ThreadAbortException
.随着Task.Delay
您可以随时提供取消令牌并优雅地杀死它.这就是我选择的一个原因Task.Delay
.请参阅http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspx
我也同意效率在这种情况下并不是最重要的.
小智 10
Delayed
会是一个更好的名称Task.Delay
- 因为它不会延迟现有任务,而是创建一个新的“延迟”任务,另一方面可以等待该任务并可能导致当前任务主体挂起。它本质上是一个计时器,但没有回调/主体。
等待延迟任务会在异步消息队列中创建一个新项目,并且不会阻塞任何线程。调用等待的同一线程将继续处理其他任务(如果有),并将在超时后(或当队列中的前面的项目完成时)返回到等待点。后台任务使用线程 - 可以在单个线程中调度和执行许多任务。另一方面,如果您碰巧调用Thread.Sleep()
该线程,该线程将被阻塞,即它将在请求的时间内停止运行,并且不会处理队列中的任何异步消息。
在.NET 中,有两种主要的并行方法。旧的有线程、线程池等。新的则基于任务、异步/等待、TPL。根据经验,您不要混合这两个领域的 API。
归档时间: |
|
查看次数: |
198320 次 |
最近记录: |