C# 如何提前結束 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 就是為了掛起當前線程,為什么又要提前終止呢?或者什么樣的場景需要這樣的操作呢?評論區歡迎你的留言。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM