專案中用到了定時器隨著服務啟動作定時任務,按指定的準點時間定時執行相關操作,但是在指定準點時間內我只想讓它執行一次,要避免重入問題的發生。
首先簡單介紹一下timer,這裡所說的timer是指的System.Timers.timer,顧名思義,就是可以在指定的間隔是引發事件。官方介紹在這裡,摘錄如下:
Timer 组件是基于服务器的计时器,它使您能够指定在应用程序中引发 Elapsed 事件的周期性间隔。然后可通过处理这个事件来提供常规处理。 例如,假设您有一台关键性服务器,必须每周 7 天、每天 24 小时都保持运行。 可以创建一个使用 Timer 的服务,以定期检查服务器并确保系统开启并在运行。 如果系统不响应,则该服务可以尝试重新启动服务器或通知管理员。 基于服务器的 Timer 是为在多线程环境中用于辅助线程而设计的。 服务器计时器可以在线程间移动来处理引发的 Elapsed 事件,这样就可以比 Windows 计时器更精确地按时引发事件。
使用這個計時器有啥好處呢?主要因為它是透過.NET Thread Pool實現的、輕量、計時精確、對應用程式及訊息沒有特別的要求。
Timer是怎麼使用的之前有寫過這篇:C# System.Timers.Timer計時器的使用和定時自動清理記憶體應用
什麼叫重入呢?這是一個有關多執行緒程式設計的概念:程式中,多個執行緒同時運行時,就可能發生同一個方法被多個行程同時呼叫的情況。當這個方法中存在一些非線程安全的程式碼時,方法重入會導致資料不一致的情況。 Timer方法重入是指使用多執行緒計時器,一個Timer處理還沒完成,到了時間,另一Timer還會繼續進入這個方法處理。
關於定時器的重入問題解決方法嘗試如下:
#1、使用鎖定lock(Object)的方法來防止重入,表示一個Timer處理正在執行,下一個Timer發生的時候發現上一個沒有執行完就等待執行,適用重入很少出現的場景。在觸發的方法中加入lock,這樣當線程2進入觸發的方法中,發現已經被鎖,會等待鎖中的程式碼處理完在執行,程式碼如下:
private static System.Timers.Timer aTimer = new System.Timers.Timer(); private static object loker=new object(); /// <summary> /// 设置定时器 /// </summary> public static void SetTimer() { //读取配置时间 try { aTimer.Interval = 30000; aTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent); aTimer.AutoReset = true;//每到指定时间Elapsed事件是到时间就触发 aTimer.Enabled = true; //指示 Timer 是否应引发 Elapsed 事件。 } catch (Exception ex) { LogManager.RecordLog(LogType.Error, "ipad数据同步出错:" +ex.Message,ex); } } private static void OnTimedEvent(Object source, ElapsedEventArgs e) { //如果当前时间是为配置的准点时间就进来 var time =Convert.ToInt32( SynchronousHelper.AppConfig.get_Items("SycTime")); if (DateTime.Now.Hour == time && DateTime.Now.Minute == 0) { //lock,这样当线程2进入触发的方法中,发现已经被锁,会等待锁中的代码处理完在执行 lock (loker) { LogManager.RecordLog(LogType.Info, "数据开始同步时间:" + e.SignalTime, null); SetTimerStart(); System.Threading.Thread.Sleep(60000); //执行完越过当前分钟,使整点内只能进来一次 } } }
2.置一個標誌,表示一個Timer處理正在執行,下一個Timer發生的時候發現上一個沒有執行完就放棄(注意這裡是放棄,而不是等待哦,看看執行結果就明白啥意思了)執行,適用重入經常出現的場景。在多執行緒下給inTimer賦值不夠安全,Interlocked.Exchange提供了一種輕量級的執行緒安全的給物件賦值的方法(感覺比較高上大,也是比較推薦的一種方法)。
private static System.Timers.Timer aTimer = new System.Timers.Timer(); private static int inTimer = 0; /// <summary> /// 设置定时器 /// </summary> public static void SetTimer() { //读取配置时间 try { aTimer.Interval = 30000; //半分钟触发一次 aTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent); aTimer.AutoReset = true;//每到指定时间Elapsed事件是到时间就触发 aTimer.Enabled = true; //指示 Timer 是否应引发 Elapsed 事件。 } catch (Exception ex) { LogManager.RecordLog(LogType.Error, "ipad数据同步出错:" +ex.Message,ex); } } private static void OnTimedEvent(Object source, ElapsedEventArgs e) { //如果当前时间是为配置的准点时间就进来 var time =Convert.ToInt32( SynchronousHelper.AppConfig.get_Items("SycTime")); if (DateTime.Now.Hour == time && DateTime.Now.Minute == 0) { //inTimer设置一个标志,表示一个Timer处理正在执行,下一个Timer发生的时候发现上一个没有执行完就放弃 if (Interlocked.Exchange(ref inTimer, 1) == 0) { LogManager.RecordLog(LogType.Info, "数据开始同步时间:" + e.SignalTime, null); SetTimerStart(); System.Threading.Thread.Sleep(60000); //执行完等待越过当前分钟,使整点内只能进来一次 Interlocked.Exchange(ref inTimer, 0); } } }
稍微總結一下,timer是一個使用挺簡單的類,拿來即用,這裡主要總結了使用timer時重入問題的解決,以前也沒思考過這個問題,解決方案也挺簡單。這裡的解決方案同時也適用多執行緒的重入問題。
以上是C#中關於Timer定時器重入問題的解決方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

C#並不總是與.NET捆綁在一起。 1)C#可以在Mono運行時環境中運行,適用於Linux和macOS。 2)在Unity遊戲引擎中,C#用於腳本編寫,不依賴.NET框架。 3)C#還可用於嵌入式系統開發,如.NETMicroFramework。

C#在.NET生態系統中扮演核心角色,是開發者的首選語言。 1)C#提供高效、易用的編程方式,結合C、C 和Java的優點。 2)通過.NET運行時(CLR)執行,確保跨平台高效運行。 3)C#支持從基本到高級的用法,如LINQ和異步編程。 4)優化和最佳實踐包括使用StringBuilder和異步編程,提高性能和可維護性。

C#是微軟在2000年發布的編程語言,旨在結合C 的強大功能和Java的簡潔性。 1.C#是一種類型安全、面向對象的編程語言,支持封裝、繼承和多態。 2.C#的編譯過程將代碼轉化為中間語言(IL),然後在.NET運行時環境(CLR)中即時編譯成機器碼執行。 3.C#的基本用法包括變量聲明、控制流和函數定義,而高級用法涵蓋異步編程、LINQ和委託等。 4.常見錯誤包括類型不匹配和空引用異常,可通過調試器、異常處理和日誌記錄來調試。 5.性能優化建議包括使用LINQ、異步編程和提高代碼可讀性。

C#是一種編程語言,而.NET是一個軟件框架。 1.C#由微軟開發,適用於多平台開發。 2..NET提供類庫和運行時環境,支持多語言。兩者協同工作,構建現代應用。

C#.NET是一個強大的開發平台,結合了C#語言和.NET框架的優勢。 1)它廣泛應用於企業應用、Web開發、遊戲開發和移動應用開發。 2)C#代碼編譯成中間語言後由.NET運行時環境執行,支持垃圾回收、類型安全和LINQ查詢。 3)使用示例包括基本控制台輸出和高級LINQ查詢。 4)常見錯誤如空引用和類型轉換錯誤可以通過調試器和日誌記錄解決。 5)性能優化建議包括異步編程和優化LINQ查詢。 6)儘管面臨競爭,C#.NET通過不斷創新保持其重要地位。

C#.NET的未來趨勢主要集中在雲計算、微服務、AI和機器學習集成以及跨平台開發三個方面。 1)雲計算和微服務:C#.NET通過Azure平台優化雲環境表現,支持構建高效微服務架構。 2)AI和機器學習集成:借助ML.NET庫,C#開發者可在應用中嵌入機器學習模型,推動智能化應用發展。 3)跨平台開發:通過.NETCore和.NET5 ,C#應用可在Windows、Linux和macOS上運行,擴展部署範圍。

C#.NET開發的最新動態和最佳實踐包括:1.異步編程提高應用響應性,使用async和await關鍵字簡化非阻塞代碼;2.LINQ提供強大查詢功能,通過延遲執行和表達式樹高效操作數據;3.性能優化建議包括使用異步編程、優化LINQ查詢、合理管理內存、提升代碼可讀性和維護性、以及編寫單元測試。

如何利用.NET構建應用?使用.NET構建應用可以通過以下步驟實現:1)了解.NET基礎知識,包括C#語言和跨平台開發支持;2)學習核心概念,如.NET生態系統的組件和工作原理;3)掌握基本和高級用法,從簡單控制台應用到復雜的WebAPI和數據庫操作;4)熟悉常見錯誤與調試技巧,如配置和數據庫連接問題;5)應用性能優化與最佳實踐,如異步編程和緩存。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3漢化版
中文版,非常好用

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)