为啥要放弃使用Thread.Sleep

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥要放弃使用Thread.Sleep相关的知识,希望对你有一定的参考价值。

.Net并没有放弃Thtead.Sleep,它的作用是挂起当进程指定的时间。而Thread.Suspend被标识为过时,即放弃了Thread.Suspend,放弃的原因是因为该挂起不能达到安全代码处挂起,可能导致无法唤醒,所以放弃了Suspend,而继承保留Thread.Sleep。在目前.46的版本中仍然没有标识为放弃,难道你用的是VS 2015?在5.0版本中标识过时了么?

但由于多线程的引入,多数时间在多线程中会用到线程模式,但多线程中使用线程模式,那只是WaitHandle类的waitOne方法或WaitAll或WaitAny等方法。以及AutoResetEvent等多线程类库的一些实现。尽管如此,只是要求在多线程程序中尽量使用类型的模式,并没有明确或暗示放弃Thread.Sleep。
参考技术A 使用System.Timers.Timer来改进我们的程序。当执行处理业务的代码时,首先把timer停止,处理完毕后,算好一次执行的时间点,赋给timer并启动,看代码版本2
复制代码
class Program

static void Main(string[] args)

var workLists = new List<string>() "任务1", "任务2", "任务3", "任务4" ;
Parallel.ForEach(workLists,
new ParallelOptions() MaxDegreeOfParallelism = 3 ,
(task) => new Work2() TaskType = task .DoWork(); );
Console.ReadLine();


复制代码
复制代码
class Work2

private Timer _workTimer;
public string TaskType get; set;
public void DoWork()

_workTimer = new System.Timers.Timer();
_workTimer.Interval = 1000;
_workTimer.Elapsed += new ElapsedEventHandler(TimerHanlder);
_workTimer.Start();

private void TimerHanlder(object sender, ElapsedEventArgs e)

_workTimer.Stop();
var interval = 1 * 60 * 1000;//处理失败,1分钟后重试
var maxTimes = 5;
var retryTimes = 0;
while (retryTimes < maxTimes)

var ok = Proccess();
if (ok)

retryTimes = maxTimes;

else

retryTimes++;
System.Threading.Thread.Sleep(interval);


var times = GetTotalSecondsForNext();
Console.WriteLine("0秒后重新执行", times);
_workTimer.Interval = times * 1000;//计算离下一次开始处理的时间
_workTimer.Start();

private bool Proccess()

Console.WriteLine("开始执行处理:0", TaskType);
return true;

private int GetTotalSecondsForNext()

//这里根据自己的业务来决定
return 3;


复制代码
特别说明一下:Main方法中的Console.ReadLine();很重要,让主线程处于等待的状态,子线程就可以一直执行下去不中断
总结
1:使用Task,而不是使用new System.Threading.Thread。是否要创建线程,应该让系统来决定,利用可复用资源
2: System.Threading.Thread.Sleep(interval);只合适在 "有限度的 " 循环场景中,比如 最多重试N次、倒计时等等本回答被提问者采纳

以上是关于为啥要放弃使用Thread.Sleep的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Thread.Sleep 如此有害

为啥没有“Thread.sleep”的“while(true)”会在 Linux 上导致 100% 的 CPU 使用率,而在 Windows 上却不会?

在控制台应用程序中,为啥在等待的异步任务中使用同步阻塞代码 (Thread.Sleep(..)) 的行为类似于多线程? [复制]

为啥 Thread.sleep 不好用

为啥 Thread.Sleep 不在秒表中注册?

为啥 thread.sleep 在第一次捕获时不停止?