我正在为我的项目使用Thread.Sleep(n)。我听说Thread.Sleep会导致性能问题但不确定。
我的要求是:
等待5分钟增量,最多30分钟(5分钟的6倍) 延迟)。在此之后,开始增加1小时并执行5次 (额外5小时)。
下面我提供了在不同场景中使用Thread.Sleep(n)的示例代码:
Thread.Sleep(1000 * 60 * 5); //-------waiting for 5 minutes
var isDownloaded = false;
try
{
var attempt = 0;
while (attempt < 11)
{
isDownloaded = TryDownloading(strPathToDownload, strFileToDownload);
if (isDownloaded)
break;
attempt++;
if (attempt < 6)
Thread.Sleep(1000 * 60 * 5); //--------waiting for 5 minutes
else
{
if (attempt < 11)
Thread.Sleep(1000 * 60 * 60); //-------waiting for 1 hour
else
break;
}
}
}
在上面的代码中,我试图下载最多11次下载尝试的文件。最初它等待5分钟,然后尝试下载首次尝试的文件,如果失败则尝试接下来的5次尝试,每次尝试间隔5分钟 。如果他们在前六次尝试失败,那么它将进行接下来的5次尝试,每次尝试间隔1小时。
所以我们决定在我们的控制台应用程序中使用Thread.Sleep来延迟时间。
这是否会导致任何问题或性能问题?
如果Thread.Sleep(n)导致性能问题,那么这将是一种更好的替代方式,而不是使用Thread.Sleep(n)?
最后,MSDN是否建议Thread.Sleep(n)有害或不应该使用?
答案 0 :(得分:7)
这绝对没问题。以下是睡眠费用:
O(1)
。睡眠的持续时间无关紧要。这是一个小而不变的成本。就是这样。
但是,有什么不好的是忙于等待或进行轮询循环,因为这会导致实际的CPU使用率。只是在睡眠或等待中花费时间不会产生CPU使用率。
TL; DR:使用睡眠进行延迟,不要使用睡眠进行轮询。
我必须说,对睡眠的厌恶有时只是训练有素的反射。在你谴责睡觉之前一定要分析具体的用例。
答案 1 :(得分:3)
不要使用ASP.NET辅助进程来运行长时间运行的任务!
应用程序池可以随时回收,您将失去睡眠线。
请考虑使用Windows服务。 您可以使用数据库或消息传递在网站和Windows服务之间进行通信。
答案 2 :(得分:2)
Thread.Sleep
对性能有害,而且我已经将它用于或多或少与您现在所做的完全相同的目的。只有我生成了几个工作线程,它们为Windows服务执行了不同的任务。部署时,这会导致服务器在使用Thread.Sleep等待时将CPU使用率固定在95%左右。
所以我重构了代码并将其更改为使用System.Threading
命名空间中的计时器,并且在空闲时它没有任何结果。开始时要复杂一些,但性能差异是巨大的。
答案 3 :(得分:1)
你最好使用Timer来执行这样的间歇性操作,因为Thread.Sleep是一个阻塞调用,并保持分配进程并冻结应用程序。
像这样: 在调用者对象中Timer t = new Timer(1000 * 60 * 5);
t.Tick += t_Tick;
t.Start();
实施事件
//event timer elapsed implementation
int count = 0;
private void t_Tick(object sender, EventArgs e)
{
if(count >=5)
t.Stop();
else{
//your code that do the work here
}