麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 編程 > .NET > 正文

為什么要放棄使用Thread.Sleep

2024-07-10 13:29:59
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

前言

此文并不是說(shuō)要完全放棄使用Thread.Sleep,而是要說(shuō)明在符合哪些情況下使用!

場(chǎng)景

很多時(shí)候,我們會(huì)需要一個(gè)定時(shí)服務(wù)來(lái)處理業(yè)務(wù)。

但并不是死死的每隔N分鐘執(zhí)行一次那種,而是在一次處理完后,算好下一次處理的時(shí)間點(diǎn)。

當(dāng)?shù)竭_(dá)此時(shí)間點(diǎn),觸發(fā)程序重新開始執(zhí)行代碼。

普遍做法

普遍的情況下,都是使用while(true){Thread.Sleep()}來(lái)實(shí)現(xiàn),廢話不多話,看代碼版本1:

class Program{  static void Main(string[] args)  {    var workLists = new List<string>() { "任務(wù)1", "任務(wù)2", "任務(wù)3", "任務(wù)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;//處理失敗,1分鐘后重試    var maxTimes = 5;    var retryTimes = 0;    while (true)    {      while (retryTimes < maxTimes)      {        var ok = Proccess(taskType);        if (ok)        {          retryTimes = maxTimes;        }        else        {          retryTimes++;          System.Threading.Thread.Sleep(interval);        }      }      var tim = GetTotalMillisecondsForNext();//計(jì)算離下一次開始處理的時(shí)間				      System.Threading.Thread.Sleep(tim);//掛起一段時(shí)間后,重新喚醒      retryTimes = 0;    }  }  private static bool Proccess(string taskType)  {    Console.WriteLine("開始執(zhí)行處理:{0}", taskType);    return true;  }  private static int GetTotalMillisecondsForNext()  {    //這里根據(jù)自己的業(yè)務(wù)來(lái)決定    return 2 * 1000;  }}

代碼簡(jiǎn)單易懂。

分析

版本1中,循環(huán)強(qiáng)制創(chuàng)建線程,并使用System.Threading.Thread.Sleep(tim)來(lái)掛起線程,然后重新喚醒。

這種方式不好之處在于:占用系統(tǒng)線程資源,是一種浪費(fèi)。如同占著茅坑不拉屎!線程是一種十分寶貴的資源,創(chuàng)建,銷毀,切換 都是相當(dāng)耗性能的。

當(dāng)Sleep的時(shí)候,就等于說(shuō):現(xiàn)在我不用,但是你也別想用。你要用?自己去Create一個(gè)。

有的人說(shuō),Sleep的時(shí)候 不占用CPU啊!對(duì),是不占用CPU ,但是占著線程資源,阻礙系統(tǒng)的線程調(diào)度!

可以參考下 這文章

Threads are a limited resource, they take approximately 200,000 cycles to create and about 100,000 cycles to destroy. By default they reserve 1 megabyte of virtual memory for its stack and use 2,000-8,000 cycles for each context switch. This makes any waiting thread a   huge  waste.

改進(jìn)

使用System.Timers.Timer來(lái)改進(jìn)我們的程序。當(dāng)執(zhí)行處理業(yè)務(wù)的代碼時(shí),首先把timer停止,處理完畢后,算好一次執(zhí)行的時(shí)間點(diǎn),賦給timer并啟動(dòng),看代碼版本2

class Program{  static void Main(string[] args)  {    var workLists = new List<string>() { "任務(wù)1", "任務(wù)2", "任務(wù)3", "任務(wù)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}秒后重新執(zhí)行", times);      _workTimer.Interval = times * 1000;//計(jì)算離下一次開始處理的時(shí)間      _workTimer.Start();    }    private bool Proccess()    {      Console.WriteLine("開始執(zhí)行處理:{0}", TaskType);      return true;    }    private int GetTotalSecondsForNext()    {      //這里根據(jù)自己的業(yè)務(wù)來(lái)決定      return 3;    }  }

特別說(shuō)明一下:Main方法中的Console.ReadLine();很重要,讓主線程處于等待的狀態(tài),子線程就可以一直執(zhí)行下去不中斷

總結(jié)

1:使用Task,而不是使用new System.Threading.Thread。是否要?jiǎng)?chuàng)建線程,應(yīng)該讓系統(tǒng)來(lái)決定,利用可復(fù)用資源

2: System.Threading.Thread.Sleep(interval);只合適在 "有限度的 " 循環(huán)場(chǎng)景中,比如 最多重試N次、倒計(jì)時(shí)等等

如果不對(duì)之處,請(qǐng)各位斧正!


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 狼伊千合综网中文 | 99riav国产在线观看 | 国产999精品久久久久 | 斗破苍穹在线免费 | 亚洲综合视频一区 | 黄色片视频在线观看 | 久久精品视频在线 | 久久激情免费视频 | 污片在线观看视频 | 久久草在线视频国产 | 嫩嫩的freehdxxx| 嗯~啊~弄嗯~啊h高潮视频 | 国产精品999在线观看 | 日韩黄在线 | 成人羞羞视频在线观看免费 | 国产精品欧美久久久久一区二区 | 狠狠干网站 | 色诱亚洲精品久久久久久 | 色阁阁69婷婷 | 万圣街在线观看免费完整版 | 在线亚洲播放 | 欧美久久一区二区 | 免费高潮在线国 | 久久久久久久久亚洲精品 | 亚洲人成中文字幕在线观看 | 久草手机视频在线观看 | 黄色免费高清网站 | 久草在线资源福利站 | 亚洲国产高清自拍 | 男女无遮挡羞羞视频 | 91九色国产视频 | 亚洲成人免费视频在线 | www.91sese| 爱射av| 狠狠干最新网址 | 久久爽精品区穿丝袜 | 欧美日本在线视频 | 免费播放欧美毛片 | av在线更新 | 中文字幕精品在线播放 | 久久99久久98精品免观看软件 |