2015-05-20 7 views
8

मैं एक खिड़कियों सेवा के निर्माण कर रहा हूँ जो एक नियमित अंतराल (एक बार प्रति मिनट) Quartz.netmisfires

का उपयोग करने में एक निर्धारित कार्य जो (लीगेसी सिस्टम से) आदेशों की एक कतार प्रक्रियाओं प्रदर्शन कर रहा है की अनदेखी करने के Quartz.net हो रही है

यदि कार्य 1 मिनट से अधिक समय लेता है, जो कुछ परिस्थितियों में असामान्य लेकिन संभव होगा, तो मैं इसे ट्रिगर्स को मिटाने वाले ट्रिगर्स को अनदेखा करना चाहता हूं।

हालांकि मुझे ऐसा होने वाला प्रतीत नहीं होता है। यह प्रसंस्करण करता है और फिर त्वरित उत्तराधिकार में चूकने वाले सभी ट्रिगर्स को तेज़ी से निकाल देता है। जैसा कि मैं समझता हूं कि आप मिस्फीर्स के लिए सीमा तय कर सकते हैं लेकिन मुझे यह काम करने में सक्षम नहीं लगता है।

मैं नौकरी पर [DisallowConcurrentExecution()] का उपयोग कर रहा हूं यह सुनिश्चित करने के लिए कि नौकरी का केवल एक उदाहरण किसी भी समय चल रहा है।

नीचे कुछ स्निपेट हैं। पहले कुछ कॉन्फ़िगरेशन जानकारी में गुजर रहा है - क्या आप मिस्फीयर थ्रेसहोल्ड सेट करते हैं?

var trigger = TriggerBuilder.Create() 
        .WithIdentity("trigger1", "group1") 
        .StartNow() 
        .WithSimpleSchedule( x => x.WithMisfireHandlingInstructionIgnoreMisfires() 
        .WithIntervalInSeconds(60) 
        .RepeatForever()) 
        .Build(); 

विचार बहुत सराहना:

NameValueCollection config = new NameValueCollection(); 
    config.Add("quartz.jobStore.misfireThreshold", "600000"); 

    schedFact = new StdSchedulerFactory(config); 

मैं क्या मान के साथ एक ट्रिगर बिल्डिंग पर ध्यान न दें misfires की सही सेटिंग होने के लिए।

नौकरी के लिए कोड: बस इस बिंदु पर किसी न किसी विचार के साथ खेल रहा है तो बस एक कंसोल ऐप में चल रहा है और यादृच्छिक रूप से नौकरी में देरी कर रहा है, इसलिए यह अंतराल पर शूट हो जाता है जो इसके लिए 10 सेकंड पर सेट होता है। कुछ देरी के बाद त्वरित उत्तराधिकार में सभी समर्थित अपवादियों की आग लग गई।

[DisallowConcurrentExecution()] 
public class SomeJob : IJob 
{ 
    public SomeJob() { } 
    public void Execute(IJobExecutionContext context) 
    { 
     Random rnd = new Random(DateTime.UtcNow.Second); 
     int delay = rnd.Next(2); 
     Console.WriteLine("Executing Job with delay of "+ delay + " at " + DateTime.UtcNow.ToString()); 

     if (delay == 1) 
     { 
      System.Threading.Thread.Sleep(1000 * 25); // sleep for 25 seconds 
     } 
    } 
} 





Example console output: 
Executing Job with delay of 1 at 21/05/2015 21:27:17 
Executing Job with delay of 1 at 21/05/2015 21:27:42 
Executing Job with delay of 0 at 21/05/2015 21:28:07 <-- stacked misfires 
Executing Job with delay of 0 at 21/05/2015 21:28:07 <-- 
Executing Job with delay of 0 at 21/05/2015 21:28:07 <-- 
Executing Job with delay of 0 at 21/05/2015 21:28:07 <-- 
Executing Job with delay of 0 at 21/05/2015 21:28:16 
Executing Job with delay of 0 at 21/05/2015 21:28:26 
Executing Job with delay of 1 at 21/05/2015 21:28:36 
Executing Job with delay of 0 at 21/05/2015 21:29:01 
Executing Job with delay of 0 at 21/05/2015 21:29:01 
Executing Job with delay of 1 at 21/05/2015 21:29:06 
+0

क्या आप अपनी नौकरी के लिए कोड पेस्ट कर सकते हैं? – LeftyX

+0

देखने के लिए धन्यवाद - मैंने नौकरी से कोड के साथ मूल पोस्ट को अपडेट किया है। –

+0

बेवकूफ सवाल: आपका ट्रिगर हर मिनट में आग लगने पर हर 30 सेकंड में आपकी नौकरी कैसे आग लग सकती है? – LeftyX

उत्तर

13

WithMisfireHandlingInstructionIgnoreMisfires(), आप क्या चाहते हैं के लिए गलत तरीका है इसका मतलब यह नहीं काम misfires ट्रिगर नहीं करेगा, तो इसका मतलब यह सभी ट्रिगर है कि जितनी जल्दी हो सके याद किया गया सक्रिय कर देगा और फिर साधारण के लिए वापस जाना होगा अनुसूची। आप जो देखते हैं वह वही है।

आपको क्या चाहिए WithMisfireHandlingInstructionNextWithRemainingCount()। यह शेड्यूलर को मिस्फीयरों को अनदेखा करने और अगले निर्धारित समय की प्रतीक्षा करने के लिए संकेत देगा। एक संक्षिप्त स्पष्टीकरण के लिए here (यह जावा शेड्यूलर के लिए है लेकिन इससे कोई फर्क नहीं पड़ता) के लिए मिस्फायरिंग रणनीतियां थोड़ा उलझन में हो सकती हैं।

सही रणनीति के साथ भी, आपको यह समझने की आवश्यकता है कि मिस्फीयर थ्रेसहोल्ड कैसे काम करता है- यदि आपको यह गलत लगता है तो आपका मिस्फ़र्ड ट्रिगर अभी भी आग लग सकता है।

प्रलेखन से: "एक मिस्फायर वह समय अवधि है जिसके द्वारा एक ट्रिगर को अपने अगले अग्नि-समय को याद किया जाना चाहिए, ताकि इसे" मिस्फायर "माना जा सके और इस प्रकार इसका मिस्फायर निर्देश लागू हो।"

आप 600000 मिलीसेकेंड के लिए मूल्य निर्धारित किया है (और यह मूल्य सभी ट्रिगर के लिए है, तो दुर्भाग्य से ट्रिगर प्रति कोई सीमा है) - आग न पकड़ना रणनीति केवल तभी लागू किया जाएगा आपके ट्रिगर आग 600000 मिलीसेकेंड समय के बाद इसे निकाल दिया जाना चाहिए था। आप अपनी आवश्यकता के हिसाब से इसे कम या बढ़ा सकते हैं।

मिस्फीयर थ्रेसहोल्ड के बारे में अधिक जानकारी के लिए, here पढ़ें।

+0

शानदार धन्यवाद, अच्छा लिंक। WithMisfireHandlingInstructionNextWithRemainingCounting पर स्विच करना और मिस्फायर थ्रेसहोल्ड को अंतराल तक सेट करना नौकरी बहुत अच्छा लगता है। –

+0

@ एब्सोलॉजिस्ट एन ने यह काम किया है, साथ ही –

+0

को ऊपर उठाना याद रखें जैसे ही मुझे 15 से अधिक प्रतिष्ठा मिलती है ... –