好久沒有更新博客了,都有點對不起這個賬號了。這次跟大家分享的是一種編程思路,沒什麼技術含量,但也許能幫得到你。 我們經常會在程式程式中用到 Sleep 這個方法。Sleep 方法用起來非常簡單,但是有個問題,就是如果 Sleep 時間過長,突然想結束 Sleep,似乎沒有什麼好的辦法,至少目前我是不 ...
好久沒有更新博客了,都有點對不起這個賬號了。這次跟大家分享的是一種編程思路,沒什麼技術含量,但也許能幫得到你。
我們經常會在程式程式中用到 Sleep 這個方法。Sleep 方法用起來非常簡單,但是有個問題,就是如果 Sleep 時間過長,突然想結束 Sleep,似乎沒有什麼好的辦法,至少目前我是不知道有什麼比較直接的辦法。當然我這裡有個間接的辦法。
我們都知道在 Sleep 的參數是毫秒級別的,而我們用的最多的是秒級別的掛起當前線程,也就是說基本都是給參數值乘以 1000 來達到秒級。那好我們就利用一下這個一點來轉換下思路來實現提前結束 Sleep。
其實思路很簡單就是大值化小。比如參數是 1000,我們可以轉換為 100(份) * 10(基數)。轉為代碼基本就是 100 * Sleep(10)。
經過稍加修飾的封裝,核心代碼如下:
1 public sealed class MySleep 2 { 3 private volatile bool _isSleep = true; 4 5 public void Over() 6 { 7 _isSleep = false; 8 } 9 10 public void Sleep(int ms) 11 { 12 const int baseTime = 10; 13 14 if (ms < baseTime) 15 { 16 System.Threading.Thread.Sleep(ms); 17 } 18 else 19 { 20 int loopCount = ms / baseTime; // 除以 baseTime,代表是 baseTime 毫秒的多少倍 21 int surplusMS = ms % baseTime; // 剩餘毫秒數 22 23 while (_isSleep && loopCount > 0) 24 { 25 System.Threading.Thread.Sleep(baseTime); 26 --loopCount; 27 } 28 29 if (_isSleep && surplusMS > 0) 30 { 31 System.Threading.Thread.Sleep(surplusMS); 32 } 33 } 34 } 35 }
調用示例:
1 static void Main(string[] args) 2 { 3 var mySleep = new MySleep(); 4 System.Threading.Tasks.Task.Factory.StartNew(() => 5 { 6 Console.WriteLine("{0} : Sleep begin.", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); 7 Stopwatch sw = new Stopwatch(); 8 sw.Start(); 9 mySleep.Sleep(10000); 10 sw.Stop(); 11 Console.WriteLine("{0} : Sleep end.", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); 12 Console.WriteLine("Total sleep {0} ms", sw.ElapsedMilliseconds); 13 }); 14 15 Console.WriteLine("Press any key to stop sleep now."); 16 Console.ReadKey(); 17 mySleep.Over(); 18 19 Console.WriteLine("Press any key to close the application."); 20 Console.ReadKey(true); 21 }
不提前終止效果:
提前結束 Sleep效果:
以上方法基本達到提前結束 Sleep 的下效果。不過在運行期間會產生一些誤差,比如 baseTime 越小,那麼產生的迴圈指令就會越多,誤差就會越大,但是會提高終止的效率。所以這一點需要自己稍微平衡下。不過我相信,更好的辦法會在評論區出現。期待各位大神的留言。
那麼問題來了。既然用了 Sleep 就是為了掛起當前線程,為什麼又要提前終止呢?或者什麼樣的場景需要這樣的操作呢?評論區歡迎你的留言。