2009-09-11 20 views
15

के लिए टाइमआउट कैसे सेट करें व्यस्त विधि + सी # के लिए टाइमआउट कैसे सेट करें।विधि

उत्तर

12

ठीक है, यहां वास्तविक जवाब है।

... 

void LongRunningMethod(object monitorSync) 
{ 
    //do stuff  
    lock (monitorSync) { 
    Monitor.Pulse(monitorSync); 
    } 
} 

void ImpatientMethod() { 
    Action<object> longMethod = LongRunningMethod; 
    object monitorSync = new object(); 
    bool timedOut; 
    lock (monitorSync) { 
    longMethod.BeginInvoke(monitorSync, null, null); 
    timedOut = !Monitor.Wait(monitorSync, TimeSpan.FromSeconds(30)); // waiting 30 secs 
    } 
    if (timedOut) { 
    // it timed out. 
    } 
} 

    ... 

यह सी # का उपयोग करने के दो सबसे मजेदार भागों को जोड़ता है। सबसे पहले, विधि को अतुल्यकालिक रूप से कॉल करने के लिए, एक प्रतिनिधि का उपयोग करें जिसमें फैंसी-पैंट BeginInvoke जादू है।

फिर, LongRunningMethod से ImpatientMethod पर एक संदेश भेजने के लिए मॉनिटर का उपयोग करें ताकि यह पता चल सके कि यह कब किया जाता है, या अगर इसे किसी निश्चित समय में नहीं सुना है, तो बस इसे छोड़ दें।

(ps- बस के बारे में मजाक कर इस किया जा रहा वास्तविक जवाब। मुझे पता है कि 2^9303 तरीके एक बिल्ली त्वचा के लिए। विशेष रूप से नेट में हैं)

+0

यह मेरे लिए काम करता है :) –

+4

यह काम करता है, लेकिन! सावधान रहें!- जब निष्पादन प्रवाह वापस आता है, तो "LongRunningMethod" अभी भी पृष्ठभूमि में चलता है! यह एक रिसाव हो सकता है। – Alex

+0

यह पूरी तरह से सच है। यह केवल अच्छा है अगर आप किसी कार्रवाई पर प्रतीक्षा करना बंद करना चाहते हैं, एक कार्रवाई को रोकें नहीं। – MojoFilter

7

आप ऐसा नहीं कर सकते, जब तक कि आप विधि को नहीं बदल देते।

  1. विधि को इस तरह से वह खुद को मापता है कि कितना समय से चल रहा है, और अगर यह कुछ सीमा से अधिक है तो समय से पहले ही रिटर्न में बनाया गया है:

    वहाँ दो तरीके हैं।

  2. विधि इस तरह से बनाई गई है कि यह एक चर/घटना पर नज़र रखता है जो कहता है कि "जब यह चर सेट होता है, कृपया बाहर निकलें", और फिर आपके पास एक और थ्रेड पहले विधि में बिताए गए समय को मापता है, और उसके बाद सेट करता है वैरिएबल जब समय बीत चुका है तो कुछ सीमा पार हो गई है।

सबसे स्पष्ट, लेकिन दुर्भाग्य से गलत, जवाब आप यहां प्राप्त कर सकते हैं "बस थ्रेड में विधि चलाएं और थ्रेड का उपयोग करें। जब यह बहुत लंबा हो गया है"।

इस तरह से सहयोग करने के लिए विधि का एकमात्र सही तरीका यह है कि यह बहुत लंबा चलने पर एक साफ निकास करेगा।

एक तीसरा तरीका भी है, जहां आप एक अलग थ्रेड पर विधि निष्पादित करते हैं, लेकिन इसे पूरा करने के इंतजार के बाद, और ऐसा करने में बहुत लंबा समय लगता है, आप बस कहते हैं "मैं इसके लिए इंतजार नहीं कर रहा हूं खत्म करो, लेकिन इसे छोड़ दें "। इस मामले में, विधि अभी भी चलती है, और अंत में खत्म हो जाती है, लेकिन वह अन्य धागा जो इसके लिए इंतजार कर रहा था, वह बस छोड़ देगा।

किसी को फोन करने और उन्हें उस पुस्तक के लिए अपने घर की खोज करने के लिए कहने के तीसरे तरीके के बारे में सोचें, और 5 मिनट के लिए फोन के अपने अंत में इंतजार करने के बाद आप बस "अरे, चक इसे" कहते हैं, और फोन रख देना। आखिरकार कि अन्य व्यक्ति को किताब मिल जाएगी और फोन पर वापस आ जाएगी, केवल यह ध्यान देने के लिए कि आप अब परिणाम की परवाह नहीं करते हैं।

0

विधियों में सी # में टाइमआउट नहीं है, जब तक कि आपके डिबगर में या ओएस का मानना ​​न हो कि आपके ऐप ने 'लटका' दिया है। फिर भी प्रसंस्करण अभी भी जारी है और जब तक आप एप्लिकेशन को मार नहीं देते हैं, तब तक एक प्रतिक्रिया वापस आती है और ऐप काम जारी रखता है।

डेटाबेस में कॉल करने के लिए टाइमआउट हो सकता है।

2

आप विधि को एक अलग थ्रेड में चला सकते हैं, और इसकी निगरानी कर सकते हैं और इसे लंबे समय तक काम करने के लिए बाहर निकलने के लिए मजबूर कर सकते हैं। एक अच्छा तरीका, यदि आप इसे इस तरह कॉल कर सकते हैं, तो Post Sharp में विधि के लिए एक विशेषता विकसित करना होगा ताकि देखने वाला कोड आपके एप्लिकेशन को कूड़ा नहीं जा रहा है।

मैं नमूना कोड (नमूना कोड हिस्सा ध्यान दें, यह काम करता है, लेकिन बहु सूत्रण से मुद्दों भुगतना सकता है, या अगर सवाल में विधि कब्जा ThreadAbortException यह टूट जाएगा) के रूप में निम्नलिखित लिखा है:

static void ActualMethodWrapper(Action method, Action callBackMethod) 
{ 
    try 
    { 
     method.Invoke(); 
    } catch (ThreadAbortException) 
    { 
     Console.WriteLine("Method aborted early"); 
    } finally 
    { 
     callBackMethod.Invoke(); 
    } 
} 

static void CallTimedOutMethod(Action method, Action callBackMethod, int milliseconds) 
{ 
    new Thread(new ThreadStart(() => 
    { 
     Thread actionThread = new Thread(new ThreadStart(() => 
     { 
      ActualMethodWrapper(method, callBackMethod); 
     })); 

     actionThread.Start(); 
     Thread.Sleep(milliseconds); 
     if (actionThread.IsAlive) actionThread.Abort(); 
    })).Start(); 
} 

निम्नलिखित मंगलाचरण के साथ:

CallTimedOutMethod(() => 
{ 
    Console.WriteLine("In method"); 
    Thread.Sleep(2000); 
    Console.WriteLine("Method done"); 
},() => 
{ 
    Console.WriteLine("In CallBackMethod"); 
}, 1000); 

मैं अपने कोड पठनीयता पर काम करने की जरूरत है।

+0

तुम अब भी एक साफ बाहर निकलें करने के लिए जब यह खत्म हो जाना चाहिए विधि में कोड लिखने की जरूरत है:

यहाँ एक नमूना कोड है। –

+0

क्या आपका मतलब थ्रेडएबॉर्ट अपवाद को पकड़ने और संसाधनों की सफाई/निकास कोड प्रदान करने जैसा कुछ है? यह वास्तव में प्रश्न में विधि पर निर्भर करेगा। –

+0

यदि "टाइमआउट" से उसका अर्थ है "मैं अपना प्रोग्राम बंद करना चाहता हूं और विधि को पूरा करने की प्रतीक्षा नहीं करता हूं", तो हाँ, थ्रेड। एबॉर्ट का उपयोग किया जा सकता है, लेकिन यह वास्तव में एकमात्र परिदृश्य है। –

0

क्या आप Asynchronous Method बना सकते हैं ताकि आप "व्यस्त" विधि पूर्ण होने पर अन्य सामान करना जारी रख सकें?

3

जबकि MojoFilter's answer अच्छा है यह अगर "लीक करने के लिए नेतृत्व कर सकते हैं LongMethod "फ्रीज। यदि आप परिणाम में रुचि नहीं रखते हैं तो आपको ऑपरेशन के करीब होना चाहिए।

public void LongMethod() 
{ 
    //do stuff 
} 

public void ImpatientMethod() 
{ 
    Action longMethod = LongMethod; //use Func if you need a return value 

    ManualResetEvent mre = new ManualResetEvent(false); 

    Thread actionThread = new Thread(new ThreadStart(() => 
    { 
     var iar = longMethod.BeginInvoke(null, null); 
     longMethod.EndInvoke(iar); //always call endinvoke 
     mre.Set(); 
    })); 

    actionThread.Start(); 
    mre.WaitOne(30000); // waiting 30 secs (or less) 
    if (actionThread.IsAlive) actionThread.Abort(); 
} 
0

मैं नियमित रूप से ऐप्स लिखता हूं जहां मुझे प्लेटफॉर्म पर समय महत्वपूर्ण कार्यों को सिंक्रनाइज़ करना होता है। यदि आप thread.abort से बच सकते हैं तो आपको चाहिए। Thread.abort उपयुक्त होने पर दिशानिर्देशों के लिए http://blogs.msdn.com/b/ericlippert/archive/2010/02/22/should-i-specify-a-timeout.aspx और http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation देखें।

  • चयनात्मक निष्पादन:: यहाँ अवधारणा मैं लागू कर रहे हैं, तो सफलता का एक उचित मौका मौजूद है (टाइमआउट या अन्य पंक्तिबद्ध आइटम के सापेक्ष सफलता परिणाम की संभावना पूरा करने की क्षमता के आधार पर) केवल चलाते हैं। यदि आप सेगमेंट में कोड तोड़ते हैं और कार्य भाग के बीच अनुमानित समय के बारे में जानते हैं, तो आप भविष्यवाणी कर सकते हैं कि आपको आगे की प्रक्रिया को छोड़ना चाहिए या नहीं। समय गणना के लिए एक ऑब्जेक्ट बिन कार्यों को एक रिकर्सिव फ़ंक्शन के साथ या एक नियंत्रक वर्ग होने से कुल समय को मापा जा सकता है जो श्रमिकों को अपेक्षित प्रतीक्षा समय जानने के लिए देखता है।
  • चुनिंदा अनाथ: सफलता की उचित संभावना मौजूद होने पर केवल वापसी के लिए प्रतीक्षा करें। अनुक्रमित कार्य एक प्रबंधित कतार में चलाए जाते हैं। कार्य जो उनके टाइमआउट या अन्य टाइमआउट के कारण जोखिम से अधिक हैं, अनाथ हैं और उनके निरंतर एक शून्य रिकॉर्ड वापस आ गया है। लंबे समय तक चलने वाले कार्यों को एसिंक कॉल में लपेटा जा सकता है। उदाहरण एसिंक कॉल रैपर देखें: http://www.vbusers.com/codecsharp/codeget.asp?ThreadID=67&PostID=1
  • सशर्त चयन: चुनिंदा निष्पादन के समान लेकिन व्यक्तिगत कार्य के बजाय समूह पर आधारित। यदि आपके कई कार्य एक दूसरे से जुड़े हुए हैं, तो एक सफलता या असफल अतिरिक्त प्रसंस्करण अप्रासंगिक प्रस्तुत करता है, निष्पादन शुरू होने से पहले चेक किया गया एक ध्वज बनाएं और लंबे समय से चलने वाले उप-कार्य शुरू होने से पहले। यह विशेष रूप से तब उपयोगी होता है जब आप समानांतर या अन्य ऐसे कतारबद्ध समरूप कार्यों का उपयोग कर रहे हैं।
3

यह एक पुराना सवाल है लेकिन अब इसका एक आसान समाधान है जो तब उपलब्ध नहीं था: कार्य!

var task = Task.Run(() => LongRunningMethod());//you can pass parameters to the method as well 
if (task.Wait(TimeSpan.FromSeconds(30))) 
    return task.Result; //the method returns elegantly 
else 
    throw new TimeoutException();//the method timed-out 
संबंधित मुद्दे