Objective
This article does not mean to completely abandon the use of thread.sleep, but to explain in what circumstances to use!
Scene
Many times, we will need a timer service to handle the business.
But it's not a dead-end execution every n minutes, but after one processing, it's time to figure out the next process.
When this point of time is reached, the trigger restarts the code execution.
Common practice
In general, it is implemented using while (true) {Thread.Sleep ()}, with no more nonsense, see Code Version 1:
Class program { static void Main (string[] args) { var worklists = new list<string> () {"Task 1", "Task 2" , "Task 3", "Task 4"}; foreach (var task in worklists) { var thread = new System.Threading.Thread (new System.Threading.ParameterizedThreadStart (Work.dowork)); Thread. Start (Task);}}}
Class Work {public static void DoWork (object target) {var tasktype = target As String; var interval = 1 * 60 * 1000;//processing failed, 1 minutes after retrying var maxtimes = 5; var retrytimes = 0; while (true) {while (Retrytimes < maxtimes) {var ok = Pro Ccess (TaskType); if (OK) {retrytimes = Maxtimes; } else {retrytimes++; System.Threading.Thread.Sleep (interval); }} var Tim = Gettotalmillisecondsfornext ();//Calculate the time from the next start of processing S Ystem. Threading.Thread.Sleep (Tim);//After a period of suspension, wake retrytimes = 0; }} private static bool Proccess (String tasktype) {Console.WriteLine ("Start execution processing: {0}", Taskty PE); return true; } private static int gettotalmillisecondsfornext () {//Here according to your business to decide return 2 * 1000; } }
The code is easy to understand.
Analysis
In version 1, the loop forces the thread to be created and uses System.Threading.Thread.Sleep (Tim) to suspend the thread and then wake up again.
The downside of this approach is that it is a waste to consume system thread resources. Like a Manger, no poo! Threading is a very valuable resource, creating, destroying, and switching are all quite performance-consuming.
When sleep, it is equal to say: Now I do not, but you also do not want to use. You want to use it? To create one yourself.
Some people say, sleep does not occupy the CPU Ah! Yes, the CPU is not occupied, but the thread resources, blocking the system's thread scheduling!
You can refer to this article
Threads is a limited resource, they take approximately 200,000 cycles to create and on 100,000 cycles to destroy. By default they reserve 1 megabyte of the virtual memory for it stack and use 2,000-8,000 cycles for each context switch.This makes any waiting thread a huge waste.
Improved
Use System.Timers.Timer to improve our programs. When executing the code to process the business, first stop the timer, after processing, calculate the time of execution, assign to the timer and start, see Code version 2
classProgram {Static voidMain (string[] args) { varWorklists =Newlist<string> () {"Task 1","Task 2","Task 3","Task 4" }; Parallel.ForEach (Worklists,NewParallelOptions () {maxdegreeofparallelism =3}, (Task)= = {NewWork2 () {tasktype =task}. DoWork (); }); Console.ReadLine (); } }
classWORK2 {PrivateTimer _worktimer; Public stringTaskType {Get;Set; } Public voidDoWork () {_worktimer=NewSystem.Timers.Timer (); _worktimer.interval= +; _worktimer.elapsed+=NewElapsedeventhandler (Timerhanlder); _worktimer.start (); } Private voidTimerhanlder (Objectsender, Elapsedeventargs e) {_worktimer.stop (); varInterval =1* -* +;//processing failed, retry after 1 minutes varMaxtimes =5; varRetrytimes =0; while(Retrytimes <maxtimes) { varOK =proccess (); if(OK) {Retrytimes=Maxtimes; } Else{retrytimes++; System.Threading.Thread.Sleep (interval); } } varTimes =Gettotalsecondsfornext (); Console.WriteLine ("{0} seconds after re-execution", times); _worktimer.interval= Times * +;//calculate the time from the next START process_worktimer.start (); } Private BOOLproccess () {Console.WriteLine ("start processing: {0}", TaskType); return true; } Private intGettotalsecondsfornext () {//It's up to your business to decide return 3; } }
In particular: Console.ReadLine () in the main method, it is important that the main thread is in a waiting state, and the child threads can be executed without interruption.
Summarize
1: Use task instead of using new System.Threading.Thread. If you want to create a thread, you should let the system decide to take advantage of the reusable resources
2:system.threading.thread.sleep (interval); only appropriate in "limited" cycle scenarios, such as Retry n times, Countdown, etc.
If the wrong place, please treatise!
Why give up using Thread.Sleep