System.Timers.Timer बनाम System.Threading.Timer


564

मैं हाल ही में कुछ संभव टाइमर की जांच कर रहा हूं, System.Threading.Timerऔर System.Timers.Timerवे हैं जो मुझे जरूरतमंद लगते हैं (क्योंकि वे थ्रेड पूल का समर्थन करते हैं)।

मैं एक खेल बना रहा हूं, और मैं सभी प्रकार की घटनाओं का उपयोग करने की योजना बना रहा हूं, विभिन्न अंतरालों के साथ, आदि।

कौन सा सबसे अच्छा होगा?

जवाबों:


362

यह लेख काफी व्यापक व्याख्या प्रदान करता है:

" .NET फ्रेमवर्क क्लास लाइब्रेरी में टाइमर क्लासेस की तुलना करना " - एक .chm फ़ाइल के रूप में भी उपलब्ध है

विशिष्ट अंतर ऐसा प्रतीत होता है कि System.Timers.Timerयह मल्टीथ्रेडेड अनुप्रयोगों की ओर सक्षम है और इसलिए इसकी SynchronizationObjectसंपत्ति के माध्यम से थ्रेड-सुरक्षित है , जबकि System.Threading.Timerविडंबना यह नहीं है कि थ्रेड-आउट-ऑफ-द-बॉक्स।

मुझे विश्वास नहीं है कि दोनों के बीच एक अंतर है क्योंकि यह संबंधित है कि आपका अंतराल कितना छोटा हो सकता है।


69
मुझे लगता है कि यह उद्धरण ज्ञानवर्धक है: "System.Windows.Forms.Timer के विपरीत, System.Timers.Timer वर्ग, डिफ़ॉल्ट रूप से, सामान्य भाषा रनटाइम (CLR) थ्रेड पूल से प्राप्त कार्यकर्ता थ्रेड पर अपने टाइमर इवेंट हैंडलर को कॉल करेगा। । [...] System.Timers.Timer वर्ग इस दुविधा से निपटने के लिए एक आसान तरीका प्रदान करता है - यह एक सार्वजनिक SynchronizingObject संपत्ति को उजागर करता है। इस संपत्ति को विंडोज फॉर्म (या विंडोज फॉर्म पर नियंत्रण) के उदाहरण के लिए सेट करना। सुनिश्चित करें कि आपके Elapsed ईवेंट हैंडलर का कोड उसी थ्रेड पर चलता है, जिस पर SynchronizingObject को तुरंत चलाया गया था। "
mic '19

7
में थ्रेड सुरक्षा अनुभाग के अनुसार Threading.Timerकी MSDN लेख , यह पूरी तरह थ्रेड-सुरक्षित है ...
पीटर

62
System.Threading.Timerके रूप में "विडंबना" नहीं है थ्रेड-सुरक्षित System.Threading.Threadऔर पूल के माध्यम से प्राप्त धागे। सिर्फ इसलिए कि ये कक्षाएं आपका हाथ lockनहीं पकड़ती हैं और कीवर्ड के उपयोग को प्रबंधित करने का मतलब यह नहीं है कि ये कक्षाएं थ्रेडसेफ़ नहीं हैं। आप यह भी कह सकते हैं कि System.Threading.Threadथ्रेडसेफ़ नहीं है, क्योंकि यह बिल्कुल सच है।
कर्क वॉक

8
इसके अलावा System.Timer.Timer अंतराल केवल Int32 System.Threading हो सकता है। Timer अंतराल Int64 तक हो सकता है
Brent

11
यह दुर्भाग्यपूर्ण है कि यह अत्यधिक भ्रामक (सबसे अच्छा) उत्तर स्वीकार किया जाता है और इसलिए अत्यधिक मतदान होता है। उत्तर में केवल सामग्री कथन केवल गलत है। SynchronizingObjectटाइमर वस्तु ही थ्रेड-सुरक्षित नहीं है। यह सिर्फ यह सुनिश्चित करता है कि टाइमर घटना को संभालने के लिए आपका कोड एक विशिष्ट थ्रेड में कहा जाता है (यदि आप उस संपत्ति को उचित रूप से सेट करते हैं)। टाइमर ऑब्जेक्ट स्वयं थ्रेड-सुरक्षित होने की गारंटी नहीं देता है, जैसा कि प्रलेखन में स्पष्ट रूप से कहा गया है। दूसरी ओर, System.Threading.Timerवस्तु है विशेष रूप से धागे की सुरक्षित किया जा रहा है के रूप में दस्तावेज।
पीटर Duniho

169

System.Threading.Timerएक सादा टाइमर है। यह आप (कार्यकर्ता पूल से) एक धागा पूल धागे पर वापस कॉल करता है।

System.Timers.Timerयह एक System.ComponentModel.Componentलपेटता है System.Threading.Timer, और एक विशेष धागे पर भेजने के लिए इस्तेमाल कुछ अतिरिक्त सुविधाएँ प्रदान करता है।

System.Windows.Forms.Timerइसके बजाय एक मूल संदेश-केवल-एचडब्ल्यूडी लपेटता है और उस HWNDs संदेश लूप में घटनाओं को बढ़ाने के लिए विंडो टाइमर का उपयोग करता है ।

यदि आपके ऐप में कोई UI नहीं है, और आप चाहते हैं कि सबसे हल्का-वजन और सामान्य-उद्देश्य .Net टाइमर संभव हो, (क्योंकि आप खुश हैं कि आपके अपने थ्रेडिंग / डिस्पैचिंग का पता चल रहा है) तो System.Threading.Timerयह फ्रेमवर्क में उतना ही अच्छा है।

मैं पूरी तरह से स्पष्ट नहीं हूं कि क्या माना जाता है कि 'थ्रेड सेफ' मुद्दे नहीं System.Threading.Timerहैं। शायद यह केवल इस प्रश्न में पूछा गया है: System.Timers.Timer vs System.Threading.Timer , या शायद हर किसी का थ्रेड-सुरक्षा :

  1. जब आप टाइमर का उपयोग कर रहे हैं तो दौड़ की स्थिति लिखना आसान है। उदाहरण के लिए यह प्रश्न देखें: टाइमर (System.Threading) धागा सुरक्षा

  2. टाइमर सूचनाओं का फिर से प्रवेश, जहां आपका टाइमर इवेंट ट्रिगर हो सकता है और पहले इवेंट को पूरा करने से पहले आपको दूसरी बार कॉल कर सकता है । उदाहरण के लिए इस प्रश्न को देखें: System.Threading.Timer और Monitor का उपयोग करके थ्रेड-सुरक्षित निष्पादन


सच में आंतरिक रूप से System.Timers.Timerउपयोग करता है System.Threading.Timerस्रोत कोड देखें ।
पेट

120

अपनी पुस्तक " सीएलआर वाया सी # " में, जेफ़ रिचर का उपयोग करने को हतोत्साहित करता है System.Timers.Timer, यह टाइमर से प्राप्त होता है System.ComponentModel.Component, इसे विजुअल स्टूडियो की डिज़ाइन सतह में उपयोग करने की अनुमति देता है। ताकि यह केवल तभी उपयोगी होगा जब आप डिज़ाइन की सतह पर टाइमर चाहते हैं।

वह System.Threading.Timerथ्रेड पूल थ्रेड पर पृष्ठभूमि कार्यों के लिए उपयोग करना पसंद करता है ।


36
यह एक डिजाइन सतह में इस्तेमाल किया जा सकता है - इसका मतलब यह नहीं है कि यह होना चाहिए, और ऐसा नहीं करने से कोई हानिकारक प्रभाव नहीं हैं। इस प्रश्न के पहले के उत्तर में लेख को पढ़ते हुए, टाइमर। थिमर थ्रेडिंग के लिए अधिक बेहतर लगता है।
स्टीफन ड्रू

6
खैर, क्या बेहतर है संदर्भ पर निर्भर करता है, है ना? जैसा कि मैं इसे समझता हूं, System.Threading.Timer थ्रेडपूल से एक नए वर्कर थ्रेड पर पारित कॉलबैक को निष्पादित करता है। जो, मुझे लगता है कि यह भी जरूरी नहीं है कि थ्रेड-सुरक्षित हो। किंदा समझ में आता है। इसलिए, सिद्धांत रूप में, आपको अपने स्वयं के श्रमिक धागे को कताई करने के बारे में चिंता नहीं करनी होगी, क्योंकि यह टाइमर आपके लिए यह करेगा। किंडा हास्यास्पद रूप से उपयोगी लगता है।
फिनिस्टर

6
System.Threading.Timerथ्रेड पूल का उपयोग करने या अपना खुद का धागा बनाने के लिए एक का उपयोग करना है। का पाठ्यक्रम इन कक्षाओं में आप के लिए तुल्यकालन संभाल नहीं है - कि के अपने काम! न तो एक थ्रेड पूल धागा, आपका अपना धागा, न ही एक टाइमर कॉलबैक लॉकिंग को हैंडल करेगा - किस वस्तु पर और किस फैशन में और किन परिस्थितियों में आपको लॉक करने की आवश्यकता है, इसके लिए अच्छे निर्णय की आवश्यकता होती है और टाइमर का थ्रेडिंग संस्करण आपको सबसे अधिक लचीलापन देता है और पठन स्तर।
कर्क वॉक

2
-1 यह विषय शुरू से ही व्यक्तिपरक है या इसका मत है। क्यों इस पर कोई ठोस जानकारी नहीं दी गई है। System.Threading.Timer को जेफ़ रिचर ने पसंद किया है
ब्रायन ओग्डेन

42

इस बारे में Microsoft से जानकारी ( MSDN पर टिप्पणी देखें ):

  • System.Timers.Timer , जो किसी ईवेंट को आग देता है और नियमित अंतराल पर एक या अधिक ईवेंट सिंक में कोड निष्पादित करता है। क्लास का उद्देश्य बहु-स्तरीय वातावरण में सर्वर-आधारित या सेवा घटक के रूप में उपयोग करना है; इसका कोई उपयोगकर्ता इंटरफ़ेस नहीं है और यह रनटाइम पर दिखाई नहीं देता है।
  • System.Threading.Timer , जो नियमित अंतराल पर एक थ्रेड पूल थ्रेड पर एक एकल कॉलबैक विधि निष्पादित करता है। कॉलबैक पद्धति को परिभाषित किया जाता है जब टाइमर त्वरित होता है और इसे बदला नहीं जा सकता है। System.Timers.Timer वर्ग की तरह, यह वर्ग एक बहु-स्तरीय वातावरण में सर्वर-आधारित या सेवा घटक के रूप में उपयोग करने के लिए अभिप्रेत है; इसका कोई उपयोगकर्ता इंटरफ़ेस नहीं है और यह रनटाइम पर दिखाई नहीं देता है।
  • System.Windows.Forms.Timer (केवल .NET फ्रेमवर्क), एक Windows प्रपत्र घटक जो किसी ईवेंट को फायर करता है और नियमित अंतराल पर एक या अधिक ईवेंट सिंक में कोड निष्पादित करता है। घटक का कोई उपयोगकर्ता इंटरफ़ेस नहीं है और इसे एकल-थ्रेडेड वातावरण में उपयोग के लिए डिज़ाइन किया गया है; यह UI थ्रेड पर निष्पादित होता है।
  • System.Web.UI.Timer (.NET Framework केवल), एक ASP.NET घटक जो नियमित अंतराल पर अतुल्यकालिक या तुल्यकालिक वेब पेज पोस्टबैक करता है।

यह उल्लेख करना दिलचस्प है कि System.Timers.Timer.NET कोर 1.0 के साथ पदावनत किया गया था, लेकिन .NET कोर 2.0 (/ .NET मानक 2.0) में फिर से लागू किया गया था। .NET मानक 2.0 के साथ लक्ष्य यह था कि .NET फ्रेमवर्क से स्विच करना जितना संभव हो उतना आसान होना चाहिए जो शायद यही कारण है कि यह वापस आया।

जब इसे हटा दिया गया था, तो .NET पोर्टेबिलिटी एनालाइज़र विज़ुअल स्टूडियो एड-इन केSystem.Threading.Timer बजाय उपयोग करने की सिफारिश की गई थी ।

ऐसा लगता है कि Microsoft System.Threading.Timerपहले एहसान करता है System.Timers.Timer

EDIT NOTE 2018-11-15: .NET कोर 1.0 के बारे में पुरानी जानकारी के बाद से मैं अपना उत्तर बदलने के लिए हाथ नहीं लगाता था।


2
ऐसा लगता है कि यह सच है: github.com/npgsql/npgsql/issues/471#issuecomment-94104090
मार्को सुल

@ टैगाओस्ट, इसका उपयोग भी सीमित है - MSDN msdn.microsoft.com/en-us/library/… देखें और प्लेटफ़ॉर्म उपलब्धता के बारे में टिप्पणी पढ़ें।
ज्योतिषी

@astrowalker - इसके लिए धन्यवाद, जिस समय मैंने टिप्पणी की इस उत्तर में लगभग कोई विवरण नहीं था। चूंकि अब इसके बारे में विस्तार से जानकारी दी जा रही है, इसलिए मैंने अपनी टिप्पणी हटा दी।
तायगोस्त

1
System.Timers.Timer अब .NET Standard 2.0 और .NET Core 2.0 और इसके बाद के संस्करण में समर्थित है। docs.microsoft.com/en-us/dotnet/api/system.timers.timer (लेख के अंत तक स्क्रॉल करें)
ली ग्रिसोम


39

एक महत्वपूर्ण अंतर जो ऊपर उल्लेखित नहीं है जो आपको पकड़ सकता है वह है System.Timers.Timer चुपचाप अपवादों को निगल जाना, जबकि System.Threading.Timerऐसा नहीं है।

उदाहरण के लिए:

var timer = new System.Timers.Timer { AutoReset = false };
timer.Elapsed += (sender, args) =>
{
    var z = 0;
    var i = 1 / z;
};
timer.Start();

बनाम

var timer = new System.Threading.Timer(x =>
{
    var z = 0;
    var i = 1 / z;
}, null, 0, Timeout.Infinite);

1
मैंने हाल ही में टाइमर के साथ इस मुद्दे को मारा। टाइमर और यह बहुत दर्दनाक है ... किसी भी विचार मैं थ्रेडिंग के साथ फिर से कैसे लिख सकता हूं। stackoverflow.com/questions/41618324/…
Tez Wingfield

7
सोर्स कोड में एक खाली कैच है। यहाँ System.Timers.Timer स्रोत कोड
16

ओमगश क्यों एमएस प्रोग्रामर वास्तव में एक ही तरह के काम करने में सक्षम नहीं हैं?
xmedeko

2
उदाहरण यह नहीं समझाता है कि एक अपवाद को कैसे निगलता है और दूसरा नहीं करता है। क्या कोई व्यक्ति विवरण भर सकता है?
शॉन

24

मुझे MSDN से एक छोटी तुलना मिली

.NET फ्रेमवर्क क्लास लाइब्रेरी में टाइमर नाम की चार कक्षाएं शामिल हैं, जिनमें से प्रत्येक अलग कार्यक्षमता प्रदान करती है:

System.Timers.Timer, जो एक घटना को आग लगाता है और नियमित अंतराल पर एक या एक से अधिक घटनाओं में कोड निष्पादित करता है। वर्ग का उद्देश्य बहु-स्तरीय वातावरण में सर्वर-आधारित या सेवा घटक के रूप में उपयोग करना है; इसका कोई उपयोगकर्ता इंटरफ़ेस नहीं है और यह रनटाइम पर दिखाई नहीं देता है।

System.Threading.Timer, जो नियमित अंतराल पर एक थ्रेड पूल थ्रेड पर एक एकल कॉलबैक विधि निष्पादित करता है। कॉलबैक पद्धति को परिभाषित किया जाता है जब टाइमर त्वरित होता है और इसे बदला नहीं जा सकता है। System.Timers.Timer वर्ग की तरह, यह वर्ग एक बहु-स्तरीय वातावरण में सर्वर-आधारित या सेवा घटक के रूप में उपयोग के लिए है; इसका कोई उपयोगकर्ता इंटरफ़ेस नहीं है और यह रनटाइम पर दिखाई नहीं देता है।

System.Windows.Forms.Timer, एक Windows प्रपत्र घटक जो किसी ईवेंट को फायर करता है और नियमित अंतराल पर एक या अधिक ईवेंट सिंक में कोड निष्पादित करता है। घटक का कोई उपयोगकर्ता इंटरफ़ेस नहीं है और इसे एकल-थ्रेडेड वातावरण में उपयोग के लिए डिज़ाइन किया गया है।

System.Web.UI.Timer, एक ASP.NET घटक जो नियमित अंतराल पर अतुल्यकालिक या तुल्यकालिक वेब पेज पोस्टबैक करता है।


1

दो वर्ग कार्यात्मक रूप से समतुल्य हैं, सिवाय इसके कि System.Timers.Timerसभी सिंक्रनाइज़ेशनऑब्जेक्ट को सेट करके ISynchronizeInvoke के माध्यम से अपने सभी टाइमर समाप्ति कॉलबैक को लागू करने का विकल्प है । अन्यथा, दोनों टाइमर थ्रेड पूल थ्रेड्स पर समाप्ति कॉलबैक को आमंत्रित करते हैं।

जब आप System.Timers.Timerकिसी Windows प्रपत्र डिज़ाइन सतह पर खींचते हैं , तो Visual Studio सिंक्रनाइज़ेशनऑब्जेक्ट को प्रपत्र ऑब्जेक्ट पर सेट करता है , जिसके कारण सभी समाप्ति कॉलबैक UI थ्रेड पर कॉल किए जाते हैं।


1

MSDN से: System.Threading.Timerएक सरल, हल्का टाइमर है जो कॉलबैक विधियों का उपयोग करता है और थ्रेड पूल थ्रेड्स द्वारा परोसा जाता है। यह विंडोज फॉर्म के साथ उपयोग करने के लिए अनुशंसित नहीं है, क्योंकि इसकी कॉलबैक उपयोगकर्ता इंटरफ़ेस थ्रेड पर नहीं होती है। System.Windows.Forms.Timerविंडोज फॉर्म के साथ उपयोग के लिए एक बेहतर विकल्प है। सर्वर-आधारित टाइमर कार्यक्षमता के लिए, आप उपयोग करने पर विचार कर सकते हैं System.Timers.Timer, जो घटनाओं को बढ़ाता है और अतिरिक्त विशेषताएं हैं।

स्रोत

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.