WPF-23 基于Timer任務調度

.NET的FCL中提供了幾個計時器,大多數初學者都不清楚他們有什么不同,那我們這節來剖解一下每個計時器的本質:

1.System.Threading.Timer

如果在一個線程池上執行一個定時的周期性的后臺線程任務他是最好的選擇,這個類是和線程池相關聯的,它告訴線程池(ThreadPool)在指定的時間執行指定的方法

2.System.Timers.Timer

這個類是對System.Threading.Timer類的封裝,所以他兩本質上是相同,在這里推薦使用System.Threading.Timer計時器

3.System.Windows.Forms.Timer

這個計時器經常和Window窗體一塊使用,而且這個單線程處理的,從放入消息隊列,再到提取,執行回調,都是一個線程完成

4.Windows.UI.Xaml.DispatcherTimer

這個類的本質就是System.Windows.Forms.Timer,微軟設計目的是被用在Windows Store

5.System.Windows.Threading.DispatcherTimer

這個類和System.Windows.Forms.Timer本質是相同的,但是這個類用在WPF中

我們以System.Threading.Timer為例來介紹一下,推薦大家在項目中用這個計時器。

df9234addb58b078a1669269e35c42b7.png

我們可以看出有4個構造函數,我們分別講解一下每個參數的用途

1、callback表示由線程池線程回調的方法,他是一個委托定義如下:

public delegate void TimerCallback(object state);

2、state 參數表示每次調用回調方法時傳遞的參數,如果沒有則為null

3、dueTime表示在調用回調方法之前等待多少毫秒

4、period表示調用callback的時間間隔

我們在做開發的時候會遇到一種場景,當我們一個回調方法執行時間>period 設置的時間,就會導致上一個方法沒有執行完,線程池就會新啟動一個線程執行相同的方法,這樣會產生多個線程同時執行一個方法,如何解決呢?我們可以在初始化Timer的時候給period參數設置為Timeout.Infinite,在回調方法中再次調用Timer.Change(3000,Timeout.Infinite) 并把peroid參數再次設置為Timeout.Infinite,下面代碼我們對Timer進行了簡單封裝:

public class SafeTimer : IDisposable
{#region Fieldsprivate Timer innerTimer;private TimerCallback safeCallback = null!;private TimerCallback originalCallback = null!;private int syncPoint;private ManualResetEvent originalCallbackCompleteEvent = new ManualResetEvent(true);#endregion#region Constructorspublic SafeTimer(TimerCallback callback){InitializeCallback(callback);innerTimer = new Timer(safeCallback);}public SafeTimer(TimerCallback callback, object state, long dueTime, long period){InitializeCallback(callback);innerTimer = new Timer(safeCallback, state, dueTime, period);}public SafeTimer(TimerCallback callback, object state, uint dueTime, uint period){InitializeCallback(callback);innerTimer = new Timer(safeCallback, state, dueTime, period);}public SafeTimer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period){InitializeCallback(callback);innerTimer = new Timer(safeCallback, state, dueTime, period);}public SafeTimer(TimerCallback callback, object state, int dueTime, int period){InitializeCallback(callback);innerTimer = new Timer(safeCallback, state, dueTime, period);}#endregion#region Private methodsprivate void InitializeCallback(TimerCallback callback){originalCallback = callback;safeCallback = new TimerCallback(NonReentryCallback);}private void NonReentryCallback(object? state){//set syncPoint to 1 if the original value is 0. syncPoint=1 indicates a method is executing.if (Interlocked.CompareExchange(ref syncPoint, 1, 0) == 0){originalCallbackCompleteEvent.Reset();try{originalCallback(state);}catch { }finally{originalCallbackCompleteEvent.Set();Interlocked.Exchange(ref syncPoint, 0);}}}#endregion#region Public methodspublic bool Change(long dueTime, long period){return innerTimer.Change(dueTime, period);}public bool Change(int dueTime, int period){return innerTimer.Change(dueTime, period);}public bool Change(TimeSpan dueTime, TimeSpan period){return innerTimer.Change(dueTime, period);}public bool Change(uint dueTime, uint period){return innerTimer.Change(dueTime, period);}public void Stop(){innerTimer.Change(Timeout.Infinite, Timeout.Infinite);originalCallbackCompleteEvent.WaitOne();}public bool Stop(int milliseconds){innerTimer.Change(Timeout.Infinite, Timeout.Infinite);return originalCallbackCompleteEvent.WaitOne(milliseconds);}#endregion#region?IDisposable?Memberspublic void Dispose(){innerTimer.Dispose();}#endregion
}

我們做個簡單的Demo來做個測試:

internal class Program
{private static SafeTimer safeTimer = null!;static void Main(string[] args){safeTimer?=?new?SafeTimer(WriteLine,?string.Empty,?2000,?Timeout.Infinite);Console.ReadLine();}public static void WriteLine(object? state){Thread.Sleep(3000);Console.WriteLine("Hello " +DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff"));safeTimer.Change(2000, Timeout.Infinite);}
}

運行結果如下:

b07b53fedda80494c5aee750f7da8cd6.png

我們看到執行是按照線性執行,沒有并行執行,達到我們預期效果,本質上是將任務調用ThreadPool.QueueUserWorkItem將任務放到線程池中執行!這節就到這里,希望對各位有收獲。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/279806.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/279806.shtml
英文地址,請注明出處:http://en.pswp.cn/news/279806.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在.NET中不安裝Office使用EPPlus生成帶圖表(Chart)的Excel報表

在開發.NET應用中可能會遇到需要生成帶圖表(Chart)的Excel報表的需求,特別是在一些ASP.NET網站中,有時候我們并不能保證Web服務器上一定安裝了Office組件,所以使用微軟的Office來生成Excel并不保證在所有情況下都使用,有時候即使W…

facebook 邀請好友_如何在Facebook上與某人解除好友

facebook 邀請好友It’s very easy for your Facebook News Feed to get cluttered. After a few years adding ukulele playing magicians you meet wandering the street and the bar staff at every bar you go to regularly, it gets overrun with people you’ll never se…

mac下npm/node的安裝和卸載、升級;node、npm升級后最后刪掉node_modules重新安裝

mac還是使用brew install簡單一些;最好使用一種安裝方式,不要多種方式互用; 更新npm到最新版本npm install -g npm更新npm到指定版本 npm -g install npm2.9.1指定安裝目錄npm install --prefix /usr/local -g npm 1、從官網https://nodejs.o…

軟件工程小組第三次正式會議

會議主題:主要確定數據庫具體內容與會時間:3月29日與會地點:圖書館小組研究室雨水612與會成員:尚卓燃、張世豪、王昊鈺、傅宇豪會議記錄: 小組成員一起討論數據庫,確定了數據庫中的實體、屬性、聯系&#…

Edison的2022年終總結

大家好,我是Edison。2022年即將結束,又到了做年終總結的時候,它是我每年的一個習慣,意味著又要開始新的征途,在開始新的征途之前回顧一下很有必要。艱難抉擇:從互聯網到制造業今年最大的變化就是又換了份工…

JNI

配置NDK,調用JNI最終會生成一個so庫,如果so庫生成了。直接在項目中使用so庫即可調用本地方法。注意:api的包名要與so庫定義的包名一致。 1什么是jni jni java native interface java本地開發接口,是JAVA和C互相調用的橋梁。 2jni有…

dvd vlc 復制_如何使用VLC翻錄DVD

dvd vlc 復制There are many ways to rip a DVD to your computer, but if you’re looking for the most straightforward option, VLC is easy and free. Besides, you probably already have VLC on your computer (and if you don’t, you should). Here, we’ll show you …

新年芯事 | 龍芯物聯網主控芯片龍芯1C102和龍芯1C103流片成功

前言近期,龍芯中科面向物聯網領域研制的主控芯片--龍芯1C102和龍芯1C103流片成功,兩款微控制器芯片各項功能測試正常,符合設計預期。 龍芯1C102主要面向智能家居以及其他物聯網設備詳細介紹龍芯1C102采用龍芯LA132處理器核心,是一…

Javascript基礎學習20問(二)

1.函數(方法):封裝執行一項專門任務的步驟的代碼序列--》重用2.參數:方法內獨有的變量,接受傳入數據,在方法中處理3.作用域:一個變量的可用范圍 全局作用域:全局變量 局部作用…

Thrift第三課 編寫腳本

警告 盡量使用tutorial下面的模板,注意腳本的格式,否則生成錯誤 使用thrift-0.9.0生成C/csharp代碼 使用的指令如下: thrift-0.9.0.exe --gen cpp thriftcom.thrift thrift-0.9.0.exe --gen csharp thriftcom.thrift 1 注釋 有如下的三種方式 1&#xff…

【加更】搭建基于chatgpt的釘釘聊天機器人

應某些小伙伴的加更請求,出一期基于釘釘上的聊天機器人,我順便加更一期,搭建一個釘釘聊天機器人的小教程。首先進入到釘釘開放平臺的后臺管理系統:https://open.dingtalk.com/進入到 應用開發->企業內部開發->機器人右上角選…

word中 有注釋標簽嗎_如何在Word中注釋圖像

word中 有注釋標簽嗎If you’re writing a document that includes images, you may want to add annotations to those images to clarify what they represent. You can add callouts to your images to point out particular parts of the image and add text to describe t…

Lang.String

StringBuilder 原文: public final class StringBuilder extends Object implements Serializable, CharSequence A mutable sequence of characters. This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This c…

牛客網暑期ACM多校訓練營(第二場)J farm (二維樹狀數組)

題目鏈接&#xff1a; https://www.nowcoder.com/acm/contest/140/J 思路&#xff1a; 都寫在代碼注釋里了&#xff0c;非常好懂。。 for_each函數可以去看一下&#xff0c;遍歷起vector數組比較方便&#xff0c;用for(int i 0;i < q[i].size();i)的話&#xff0c;是會有一…

微軟IE 9 Beta全程體驗圖集

微軟剛剛更新了IE 9 Beta的新頁面&#xff0c;此次發布的Beta版本一共有27個國家的語言&#xff0c;其中也包括了簡體中文和香港和臺灣的繁體中文版。 點擊此處進入下載頁面&#xff1a; http://windows.microsoft.com/zh-CN/internet-explorer/download/ie-9/worldwide IE9的熱…

.net core中Quartz的使用方法

我們在日常開發中&#xff0c;總會遇到這樣的需求&#xff1a;每隔一段時間&#xff0c;執行一次某個任務。固定某個時間執行任務&#xff0c;例如凌晨12點對當天的數據進行統計。每個月的第幾天&#xff0c;執行某個任務。Quartz.Net是根據Java的Quartz用C#改寫而來&#xff0…

AspectJ學習筆記

介紹 AspectJ是一個基于Java語言的AOP框架Spring2.0以后新增了對AspectJ切點表達支持AspectJ是AspectJ1.5新增功能&#xff0c;通過JDK5注解技術&#xff0c;允許Bean類中定義切面&#xff0c;新版本Spring框架&#xff0c;建議使用AspectJ方式來開發AOP主要用途&#xff1a;自…

windows10訪客_如何在Windows 10中創建訪客帳戶

windows10訪客If you find that your guests are asking fairly often to use your computer temporarily to check their email or look something up on the web, you don’t have to let them use your personal account or create a special account for each guest. 如果發…

C#使用 System.Net.Mail發送郵件功能

介紹System.Net.Mail命名空間是在.NET Framework中新增的&#xff0c;該命名空間提供了發送電子郵件的功能。通過對本章的學習&#xff0c;讀者可以輕松地使用.NET Framework提供的類庫來發送電子郵件。System.Net.Mail 命名空間包含用于將電子郵件發送到SMTP服務器的類&#x…

初識smarty

個人體會(不完全正確)&#xff1a;就是smarty就是為了更好的使得php/html結合做出來的一個框架。 , 轉載于:https://www.cnblogs.com/nul1/p/9357694.html