2013-08-29 8 views
5

मूल विधि बुला की तरह है:समय बाहर एक विधि कॉल

public string AskAPI(string uri) 
{ 
    return api.Query(uri); 
} 

जहां एपीआई बस एक आयातित dll संदर्भ है।

अभी मैं AskAPI विधि में एक टाइम आउट फीचर जोड़ना चाहता हूं, ताकि अगर api.Query 30 सेकंड से अधिक समय लेता है, तो AskAPI अपवाद फेंक देगा।

लगता है कि मैं इसे काम नहीं कर पाऊंगा। क्या कोई इस बारे में अपने विचार साझा कर सकता है?

धन्यवाद!

+0

आपको टाइमआउट कार्यक्षमता जोड़ने के लिए 'api.Query' को संशोधित करने में सक्षम होना होगा। जैसा कि आपने इस बारे में कोई जानकारी नहीं दी है कि यह क्या है, आपको यह बताना असंभव है कि ऐसा कैसे करें। (कॉल के आसपास समय निकालने का कोई तरीका नहीं है, क्योंकि आपके पास यहां पोस्ट किए गए कार्यों के आधार पर इसे बाधित करने का कोई तरीका नहीं है।) –

+0

@KenWhite api.Query मेरे नियंत्रण में नहीं है। इसका मतलब है कि इसे संपादित किए बिना, मैं AskAPI विधि का समय नहीं निकाल सकता? – jamesdeath123

+0

मैं इसका उत्तर नहीं दे सकता, क्योंकि आपने पूरी तरह से किसी भी अन्य जानकारी के साथ कोड की बिल्कुल तीन पंक्तियां प्रदान नहीं की हैं ('{}' गिनती नहीं है)। जो आपने पोस्ट किया है उसके आधार पर, जवाब "नहीं, आप नहीं कर सकते"। –

उत्तर

8

आप Tasks इस्तेमाल कर सकते हैं यह करने के लिए, यहाँ एक उदाहरण है: एक TimeoutException उपयोग करने के लिए सुझाव देने के लिए Guillaume को

public string AskAPI(string uri, int millis) 
{ 
    using (var task = new Task<string>(() => api.Query(uri))) 
    { 
     task.Start(); 
     task.Wait(millis); 
     if (!task.IsCompleted) throw new TimeoutException(); 
     return task.Result; 
    } 
} 

धन्यवाद।

लेकिन जैसा कि जिम मिशेल बताते हैं, यह कार्य को पूरा करने से नहीं रोकेगा, इस मामले में यदि आप जिस एपीआई को कॉल कर रहे हैं उसे संशोधित कर सकते हैं तो यह सबसे अच्छा होगा क्योंकि आप रद्दीकरण टोकन क्लास का पूर्ण उपयोग कर सकते हैं जो इस तरह की चीज के लिए बनाया गया था।

public T Await<T>(Func<T> fun, int millis) 
{ 
    using (var cancel = new CancellationTokenSource(millis)) 
    using (var task = new Task<T>(() => 
    { 
     T result = default(T); 
     var thread = new Thread(() => result = fun()); 
     thread.Start(); 
     while (!cancel.Token.IsCancellationRequested && thread.IsAlive) ; // Wait for a sign from above 
     thread.Abort(); 
     cancel.Token.ThrowIfCancellationRequested(); 
     return result; 
    }, cancel.Token)) 
    { 
     task.Start(); 
     task.Wait(millis); 
     cancel.Cancel(); 
     if (!task.IsCompleted) throw new TimeoutException(); 
     return task.Result; 
    } 
} 

और फिर यह कहते हैं:

उसके अलावा, केवल अन्य त्वरित समाधान मैं के बारे में सोच सकते हैं (अनुचित हो सकता है) विधि रैप करने के लिए (या गठबंधन) कुछ इस तरह से किया जाएगा का उपयोग कर:

Await(() => AskAPI("http://some.uri"), 30000); 
+1

'अपवाद' फेंक न दें। 'टाइमआउट अपवाद' फेंको। – Guillaume

+1

@Guillaume इसके लिए धन्यवाद, मुझे इसे देखने के लिए समय लेना चाहिए था। =) – sgbj

+2

लेकिन कार्य निष्पादित करना जारी है, है ना? यही है, 'api.Query' निरस्त नहीं किया गया है? –

संबंधित मुद्दे