• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            colorful

            zc qq:1337220912

             

            關(guān)于定時(shí)器

            http://www.iwms.net/n1251c13.aspx

            定時(shí)器是個(gè)很有意思的東西,它很有用,但我認(rèn)為這不是現(xiàn)代計(jì)算機(jī)的結(jié)構(gòu)所擅長(zhǎng)的事情。
            計(jì)算機(jī)適合做那些很大量的簡(jiǎn)單重復(fù)工作,或者根據(jù)請(qǐng)求做出回應(yīng)。

            DOS時(shí)代是沒(méi)有進(jìn)程線程等概念的,那時(shí)候要想做到定時(shí)真是有些麻煩
            通常的做法是死循環(huán)不斷監(jiān)測(cè)時(shí)間,發(fā)現(xiàn)時(shí)間到了就做特定的事情
            當(dāng)然你可以用delay,來(lái)指定等待多長(zhǎng)時(shí)間,但是如果你一邊要響應(yīng)用戶(hù)的操作,比如輸入,一邊要定時(shí)做些
            事情就是一件麻煩的事了

            當(dāng)然有些人可以這樣做,截取系統(tǒng)的時(shí)鐘中斷(我忘了中斷號(hào)是多少了),每秒鐘有18.2次
            當(dāng)這些做法都不是很優(yōu)雅。但DOS時(shí)代只能這樣湊合著了

            Windows是個(gè)偉大的進(jìn)步,系統(tǒng)提供了Timer支持,但是問(wèn)題是這個(gè)定時(shí)器并不準(zhǔn)時(shí)而且有時(shí)候根本不能用。

            Win32 API中有個(gè)SetTimer函數(shù),可以為一個(gè)窗口創(chuàng)建一個(gè)定時(shí)器,這個(gè)定時(shí)器會(huì)定時(shí)產(chǎn)生消息WM_TIMER也可以調(diào)用
            指定的回調(diào)函數(shù),其實(shí)這都是一樣的,因?yàn)槎际菃尉€程的。

            單線程的定時(shí)器會(huì)有很多問(wèn)題,首先是不準(zhǔn)時(shí),定時(shí)器只是定時(shí)把消息WM_TIMER訪到線程的消息隊(duì)列里,但是并不保證消息會(huì)立刻被響應(yīng),如果
            碰巧系統(tǒng)比較忙,那么消息可能會(huì)在隊(duì)列里放一端時(shí)間才被響應(yīng),還會(huì)造成本來(lái)應(yīng)該間隔一段時(shí)間發(fā)生的消息響應(yīng)連續(xù)發(fā)生了

            解決方法通常是

            OnTimer(...)
            {
             //Timer process.....
             
             MSG msg;
             While(PeekMessage(&msg, m_hWnd, WM_TIMER, WM_TIMER, PM_REMOVE));
            }
            在當(dāng)前Timer處理中,把消息隊(duì)列里的WM_TIMER消息,清除掉。

            更糟的是如果你不去調(diào)用GetMessage,那么就不會(huì)有Timer發(fā)生了。
            這個(gè)問(wèn)題直到win xp都沒(méi)什么改變,似乎微軟并不打算在Win32 API中解決這個(gè)問(wèn)題了。

            .NET Framework為我們帶來(lái)了新的解決方案

            .NET Framework提供三種Timer

            Server Timers        System.Timers.Timer
            Thread Timers       System.Threading.Timer
            Windows Timers   System.Windows.Forms.Timer

            其中Windows Timers只是提供了和WinAPI 一樣的Timer,仍然是基于消息,仍然是單線程

            其它兩個(gè)就不同了,他們是基于線程池的Thread Pool,這樣最大的好處在于,產(chǎn)生的時(shí)間間隔準(zhǔn)確均勻。
            Server Timers  和 Thread Timers 的不同在于ServerTimers 是基于事件的,Thread Timers是基于回調(diào)函數(shù)

            我更喜歡Thread Timer,比較輕量級(jí)方便易用。

            但是這樣的Timer也有問(wèn)題,就是由于時(shí)多線程定時(shí)器,就會(huì)出現(xiàn)如果一個(gè)Timer處理沒(méi)有完成,到了時(shí)間下一個(gè)
            照樣會(huì)發(fā)生,這就會(huì)導(dǎo)致重入問(wèn)題

            對(duì)付重入問(wèn)題通常的辦法是加鎖,但是對(duì)于 Timer卻不能簡(jiǎn)單的這樣做,你需要評(píng)估一下

            首先Timer處理里本來(lái)就不應(yīng)該做太需要時(shí)間的事情,或者花費(fèi)時(shí)間無(wú)法估計(jì)的事情,比同遠(yuǎn)方的服務(wù)器建立一個(gè)網(wǎng)絡(luò)連接,這樣的做法盡量避免

            如果實(shí)在無(wú)法避免,那么要評(píng)估Timer處理超時(shí)是否經(jīng)常發(fā)生,如果是很少出現(xiàn),那么可以用lock(Object)的方法來(lái)防止重入
            如果這種情況經(jīng)常出現(xiàn)呢?那就要用另外的方法來(lái)防止重入了

            我們可以設(shè)置一個(gè)標(biāo)志,表示一個(gè)Timer處理正在執(zhí)行,下一個(gè)Timer發(fā)生的時(shí)候發(fā)現(xiàn)上一個(gè)沒(méi)有執(zhí)行完就放棄執(zhí)行

            static  int inTimer = 0;
            public static void threadTimerCallback(Object obj)
            {
                 if ( inTiemr == 0 )
                {
                     inTimer = 1;         

                     Console.WriteLine("Time:{0}, \tThread ID:{1}", DateTime.Now, Thread.CurrentThread.GetHashCode());
                     Thread.Sleep(2000);

                     inTimer = 0;
                  }
            }

            但是在多線程下給inTimer賦值不夠安全,還好Interlocked.Exchange提供了一種輕量級(jí)的線程安全的給對(duì)象賦值的方法

             static int inTimer = 0;
             public static void threadTimerCallback(Object obj)
             {
                   if ( Interlocked.Exchange(ref inTimer, 1) == 0 )
                  {
                       Console.WriteLine("Time:{0}, \tThread ID:{1}", DateTime.Now, Thread.CurrentThread.GetHashCode());
                       Thread.Sleep(250);

                       Interlocked.Exchange(ref inTimer, 0);
                  }
             }

            posted on 2013-12-18 19:29 多彩人生 閱讀(368) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            留言簿(3)

            隨筆分類(lèi)

            隨筆檔案

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            亚洲人成精品久久久久| 日韩亚洲欧美久久久www综合网| 国产91久久综合| 久久久久国产亚洲AV麻豆| 久久丝袜精品中文字幕| 久久久久久久久久久| 99久久精品费精品国产一区二区| 国产69精品久久久久99尤物| 伊色综合久久之综合久久| 国产成人精品久久一区二区三区 | 精品久久久无码中文字幕| 国产A三级久久精品| 久久福利青草精品资源站免费| 欧美激情精品久久久久久| 国产美女久久精品香蕉69| 久久久久国产精品三级网| 国产成年无码久久久久毛片| 亚洲精品WWW久久久久久| 欧美久久综合性欧美| 久久综合给合久久国产免费| 久久久久亚洲精品无码网址| 久久无码av三级| 精品综合久久久久久888蜜芽| 久久亚洲国产精品123区| 国产福利电影一区二区三区,免费久久久久久久精 | 国产精品熟女福利久久AV| 浪潮AV色综合久久天堂| 久久99久久99精品免视看动漫| www亚洲欲色成人久久精品| 久久91精品国产91久久麻豆| 久久99精品国产麻豆宅宅| 久久综合久久综合亚洲| 久久艹国产| 狠狠久久综合伊人不卡| 久久国产成人午夜AV影院| 国产99久久久国产精品~~牛| 国产精品久久久福利| 久久久久久久尹人综合网亚洲 | 国产日韩欧美久久| 亚洲狠狠久久综合一区77777| 韩国三级大全久久网站|