欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.NET Framework中定時器timer的單線程與多線程使用講解

 更新時間:2016年04月27日 10:53:10   作者:winnow  
這篇文章主要介紹了.NET Framework中定時器timer的單線程與多線程使用講解,單線程定時器在性能方面不如多線程,但是可以做到線程安全,需要的朋友可以參考下

如果你需要使用規(guī)律的時間間隔重復執(zhí)行一些方法,最簡單的方式是使用定時器(timer)。與下邊的例子相比,定時器可以便捷、高效地使用內(nèi)存和資源:

new Thread (delegate() {
             while (enabled)
             {
              DoSomeAction();
              Thread.Sleep (TimeSpan.FromHours (24));
             }
            }).Start();

這不僅僅會永久占用一個線程,而且如果沒有額外的代碼,DoSomeAction每天都會發(fā)生在更晚的時間。定時器解決了這些問題。

.NET Framework 提供了 4 種定時器。下邊兩個類是通用的多線程定時器:

(1)System.Threading.Timer
(2)System.Timers.Timer
另外兩個是專用的單線程定時器:

(3)System.Windows.Forms.Timer (Windows Forms 的定時器)
(4)System.Windows.Threading.DispatcherTimer (WPF 的定時器)
多線程定時器更加強大、精確并且更加靈活,而單線程定時器對于一些簡單的更新 Windows Forms 和 WPF 控件的任務來說是安全的,并且更加便捷。

1.多線程定時器Permalink

System.Threading.Timer是最簡單的多線程定時器:它僅僅有一個構(gòu)造方法和兩個普通方法(取悅于極簡主義者,還有本書作者?。?。在接下來的例子中,一個定時器在 5 秒鐘之后調(diào)用Tick方法來打印 “ tick… “,之后每秒打印一次直到用戶按下回車鍵:

using System;
using System.Threading;

class Program
{
 static void Main()
 {
  // 首次間隔 5000ms,之后間隔 1000ms
  Timer tmr = new Timer (Tick, "tick...", 5000, 1000);
  Console.ReadLine();
  tmr.Dispose();     // 停止定時器并執(zhí)行清理工作
 }

 static void Tick (object data)
 {
  // 這里運行在一個線程池線程上
  Console.WriteLine (data);     // 打印 "tick..."
 }
}

之后可以通過調(diào)用Change方法來改變定時器的時間間隔。如果你希望定時器只觸發(fā)一次,可以指定Timeout.Infinite作為構(gòu)造方法的最后一個參數(shù)。

.NET Framework 在System.Timers命名空間下提供了另一個名字相同的定時器類。它只是封裝了 System.Threading.Timer,并在使用完全相同的底層引擎的前提下提供額外的便利。下面是增加功能的簡介:

(1)實現(xiàn)了Component,允許用于 Visual Studio 的設計器中。
(2)Interval屬性代替了Change方法。
(3)Elapsed事件代替了回調(diào)委托。
(4)Enabled屬性用于開始或停止定時器(默認值是false)。
(5)Start和Stop方法,避免對Enabled屬性感到困惑。
(6)AutoReset標識來指定是否為可重復的事件(默認為true)。
SynchronizingObject屬性提供Invoke和BeginInvoke方法,用于在 WPF 和 Windows Forms 控件上安全調(diào)用方法。
這有個例子:

using System;
using System.Timers;  // 命名空間是 Timers 而不是 Threading

class SystemTimer
{
 static void Main()
 {
  Timer tmr = new Timer();    // 無需任何參數(shù)
  tmr.Interval = 500;
  tmr.Elapsed += tmr_Elapsed;  // 使用事件代替委托
  tmr.Start();          // 開啟定時器
  Console.ReadLine();
  tmr.Stop();          // 停止定時器
  Console.ReadLine();
  tmr.Start();          // 重啟定時器
  Console.ReadLine();
  tmr.Dispose();         // 永久停止定時器
 }

 static void tmr_Elapsed (object sender, EventArgs e)
 {
  Console.WriteLine ("Tick");
 }
}

多線程定時器使用線程池來允許少量線程服務多個定時器。這意味著,回調(diào)方法或Elapsed事件每次可能會在不同的線程上觸發(fā)。此外,不論之前的Elapsed是否完成執(zhí)行,Elapsed總是幾乎按時觸發(fā)。因此,回調(diào)方法或事件處理器必須是線程安全的。

多線程定時器的精度依賴于操作系統(tǒng),通常是在 10-20 ms 的區(qū)間。如果需要更高的精度,你可以使用本地互操作(native interop)來調(diào)用 Windows 多媒體定時器,可以讓精度提升到 1 ms。它定義在 winmm.dll 中,首先調(diào)用timeBeginPeriod來通知操作系統(tǒng)你需要更高的定時器精度,然后調(diào)用timeSetEvent來啟動多媒體定時器。當使用完成后,調(diào)用timeKillEvent停止定時器,最后調(diào)用timeEndPeriod通知操作系統(tǒng)你不在需要更高的定時器精度了??梢酝ㄟ^搜索關(guān)鍵字 dllimport winmm.dll timesetevent 在網(wǎng)上找到完整的例子。

2.單線程定時器Permalink

.NET Framework 提供了兩個定時器,為消除WPF 和 Windows Forms 應用程序的線程安全問題而設計:

System.Windows.Threading.DispatcherTimer(WPF)
System.Windows.Forms.Timer(Windows Forms)
單線程定時器不是被設計成能在其特定的環(huán)境外工作的。例如,如果在 Windows 系統(tǒng)服務應用程序中使用 Windows Forms 定時器,Timer事件不會觸發(fā)!

它們暴露的成員都像System.Timers.Timer一樣(Interval、Tick、Start和Stop),并且用法也類似。但是不同之處在于其內(nèi)部是如何工作的。它們不是使用線程池來產(chǎn)生定時器事件,WPF 和 Windows Forms 定時器依賴于 UI 模型的底層消息循環(huán)機制(message pumping mechanism)。意味著Tick事件總是在創(chuàng)建該定時器的那個線程觸發(fā),在通常的程序中,它也就是管理所有 UI 元素和控件的那個線程。這有很多好處:

單線程計時器比較安全,對于更新 Windows Forms controls或者WPF這種簡單任務來說更方便。在WPF或Windows Forms中安全的調(diào)用方法的SynchronizingObject對象。
單線程計時器是被設計成屬于他們執(zhí)行環(huán)境的計時器,如果你在一個Windows服務應用程序中使用Windows Forms的Timer,timer 事件并不會被觸發(fā),只有在對應的環(huán)境下才會被觸發(fā)。
像System.Timers.Timer一樣,他們也提供了相同的成員(Interval,Tick,Start,Stop),但是他們內(nèi)部的工作原理不同,WPF和Windows Forms的計時器使用消息循環(huán)機制來取代線程池產(chǎn)生消息的機制。

你可以不必考慮線程安全。
新的Tick在之前的Tick完成執(zhí)行前不會觸發(fā)。
你可以直接在Tick時間事件的處理代碼中更新 UI 控件,而不需要調(diào)用Control.Invoke或Dispatcher.Invoke。
這聽起來好的難以置信,直到你意識到使用這些定時器的程序并不是真正的多線程,不會有并行執(zhí)行。一個線程服務于所有定時器,并且還處理 UI 事件。這帶來了單線程定時器的缺點:

除非Tick事件處理器執(zhí)行的很快,否則 UI 會失去響應。
這使得 WPF 和 Windows Forms 定時器僅適用于小任務,通常就是那些更新 UI 外觀的任務(例如,顯示時鐘或倒計時)。否則,你就需要多線程定時器。

在精度方面,單線程定時器與多線程定時器類似(幾十毫秒),但是通常精度更低,因為它們會被其它 UI 請求(或其它定時器事件)推遲。

單線程計時器基于Windows消息循環(huán),應用程序會同步的處理計時器的消息。會發(fā)現(xiàn)UI界面相應速度比較慢。解決這個問題的方法是使用多線程計時器。
單線程計時器的缺點:除非Tick事件的處理代碼執(zhí)行的非???,否則UI界面會變得響應很慢。所以 WPF和Windows Forms的計時器都非常適合小任務,尤其是界面更新的任務。例如時鐘和計數(shù)顯示。否則,你需要一個多線程計時器


相關(guān)文章

  • ASP.NET Core實現(xiàn)文件上傳和下載

    ASP.NET Core實現(xiàn)文件上傳和下載

    這篇文章主要為大家詳細介紹了ASP.NET Core實現(xiàn)文件上傳和下載,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • 使用Visual Studio 2017寫靜態(tài)庫

    使用Visual Studio 2017寫靜態(tài)庫

    這篇文章主要為大家詳細介紹了Visual Studio2017寫靜態(tài)庫的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • c# .net 生成圖片驗證碼的代碼

    c# .net 生成圖片驗證碼的代碼

    c# .net 生成圖片驗證碼的代碼...
    2007-03-03
  • asp.net中穿透Session 0 隔離(二)

    asp.net中穿透Session 0 隔離(二)

    上一篇我們已經(jīng)對Session 0 隔離有了進一步認識,如果在開發(fā)過程中確實需要服務與桌面用戶進行交互,可以通過遠程桌面服務的API 繞過Session 0 的隔離完成交互操作
    2012-11-11
  • ASP.NET 頁生命周期概述(小結(jié))

    ASP.NET 頁生命周期概述(小結(jié))

    了解個掌握ASP.NET頁面生命周期是非常必要的,這有助于我們更加靈活的控制頁面,以我們需要的方式編程開發(fā)。本文詳細的介紹了ASP.NET 頁生命周期,感興趣的可以了解一下
    2018-11-11
  • ASP.NET MVC 項目直接預覽PDF文件

    ASP.NET MVC 項目直接預覽PDF文件

    本文主要介紹了ASP.NET MVC項目實現(xiàn)直接預覽PDF文件的方法,具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • asp.net 獲取指定文件夾下所有子目錄及文件(樹形)

    asp.net 獲取指定文件夾下所有子目錄及文件(樹形)

    asp.net獲取指定文件夾下所有子目錄及文件,現(xiàn)在有asp.net的站的就是用這樣的原理顯示文件的
    2008-07-07
  • Cookies的各方面知識(基礎(chǔ)/高級)深度了解

    Cookies的各方面知識(基礎(chǔ)/高級)深度了解

    Cookies想必所有人都了解本文將圍繞Cookies基礎(chǔ)知識(什么是Cookies/Cookies如何傳遞/Cookies如何存儲/Cookies如何查看)Cookies高級知識/Cookie的限制等等方方面面深入了解,感興趣的朋友可以參考下,或許對你學習cookies有所幫助
    2013-02-02
  • swagger上傳文件并支持jwt認證的實現(xiàn)方法

    swagger上傳文件并支持jwt認證的實現(xiàn)方法

    今天通過本文給大家分享swagger上傳文件并支持jwt認證的實現(xiàn)方法,文中提到了安裝方法及實現(xiàn)代碼,感興趣的朋友跟隨腳本之家小編一起學習吧
    2018-05-05
  • Winform OpenFileDialog打開文件對話框

    Winform OpenFileDialog打開文件對話框

    這篇文章主要為大家詳細介紹了Winform OpenFileDialog打開文件對話框 的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03

最新評論