2012-01-15 19 views
73

मैं निम्नलिखित कोड है:कैच ब्लॉक में प्रतीक्षा

WebClient wc = new WebClient(); 
string result; 
try 
{ 
    result = await wc.DownloadStringTaskAsync(new Uri("http://badurl")); 
} 
catch 
{ 
    result = await wc.DownloadStringTaskAsync(new Uri("http://fallbackurl")); 
} 

असल में मैं किसी URL से डाउनलोड करना चाहते है और जब यह एक अपवाद मैं अन्य यूआरएल से डाउनलोड करना चाहते के साथ विफल रहता है। निश्चित रूप से दोनों समय async। हालांकि कोड,

त्रुटि CS1985 की वजह से संकलन नहीं करता है: एक पकड़ने खंड के शरीर में का इंतजार नहीं कर सकते

ठीक है, यह किसी भी कारण से मना किया है, लेकिन क्या सही कोड पैटर्न यहाँ है?

संपादित करें:

अच्छी खबर यह है कि C# 6.0 will likely allow await calls both in catch and finally blocks है।

उत्तर

87

अद्यतन:C# 6.0 supports await in catch


ओल्ड उत्तर:

WebClient wc = new WebClient(); 
string result = null; 
bool downloadSucceeded; 
try 
{ 
    result = await wc.DownloadStringTaskAsync(new Uri("http://badurl")); 
    downloadSucceeded = true; 
} 
catch 
{ 
    downloadSucceeded = false; 
} 

if (!downloadSucceeded) 
    result = await wc.DownloadStringTaskAsync(new Uri("http://fallbackurl")); 
+7

धन्यवाद svick, कि काफी स्पष्ट है, कुछ भी बेहतर, async को अधिक कनेक्ट? –

+0

मुझे ऐसा नहीं लगता कि ऐसा कुछ भी मौजूद है। – svick

+3

आपके मामले में, आप कार्य निरंतरता का भी उपयोग कर सकते हैं। लेकिन 'svick' के जवाब में कोड निरंतरता का उपयोग कर कोड से क्लीनर है। –

9

यह काम करने के लिए लगता है: आपको लगता है कि कोड catch ब्लॉक से await स्थानांतरित करने के लिए एक ध्वज का उपयोग कर फिर से लिखने कर सकते हैं।

 WebClient wc = new WebClient(); 
     string result; 
     Task<string> downloadTask = wc.DownloadStringTaskAsync(new Uri("http://badurl")); 
     downloadTask = downloadTask.ContinueWith(
      t => { 
       return wc.DownloadStringTaskAsync(new Uri("http://google.com/")).Result; 
      }, TaskContinuationOptions.OnlyOnFaulted); 
     result = await downloadTask; 
24

कैच ब्लॉक में प्रतीक्षा कर रहा है रोसलिन as shown here (Listed under Await in catch/finally) के अंतिम उपयोगकर्ता पूर्वावलोकन के रूप में अब संभव है और सी # में शामिल किया जाएगा 6.

सूचीबद्ध उदाहरण है

try … catch { await … } finally { await … } 

अद्यतन: जोड़ा गया नया लिंक, और यह सी # 6

0

पर होगा आप await डाल सकते हैं के बाद पकड़ ब्लॉक के बाद label, और कोशिश ब्लॉक में goto डालें। (नहीं, वास्तव में! गोटो यह बुरा नहीं है!)

0

इसी तरह, मैं एक पकड़ ब्लॉक में इंतजार करने में असमर्थ था। हालांकि, मैं ध्वज सेट करने में सक्षम था, और अगर किसी कथन में नीचे ध्वज का उपयोग करता हूं (नीचे कोड)

------------------------

  try 
     { 
      await AsyncFunction(...); 
     } 

     catch(Exception ex) 
     { 
      Utilities.LogExceptionToFile(ex).Wait(); 
      //instead of "await Utilities.LogExceptionToFile(ex);" 
     } 

(देखें Wait() समाप्त)

4

इस आज़मा कर देखें फ़ॉलबैक कार्य पर प्रतीक्षा करने के बाद अपवाद को पुनर्स्थापित करने के लिए उपयोग करें:

ExceptionDispatchInfo capturedException = null; 
try 
{ 
    await SomeWork(); 
} 
catch (Exception e) 
{ 
    capturedException = ExceptionDispatchInfo.Capture(e); 
} 

if (capturedException != null) 
{ 
    await FallbackWork(); 
    capturedException.Throw(); 
} 
1

पैटर्न मैं: ---------------...

boolean exceptionFlag = false; 

try 
{ 
do your thing 
} 
catch 
{ 
exceptionFlag = true; 
} 

if(exceptionFlag == true){ 
do what you wanted to do in the catch block 
} 
2

सी # 6.0 का उपयोग करें।देखना यह Link

public async Task SubmitDataToServer() 
{ 
    try 
    { 
    // Submit Data 
    } 
    catch 
    { 
    await LogExceptionAsync(); 
    } 
    finally 
    { 
    await CloseConnectionAsync(); 
    } 
} 
1

आप एक लैम्ब्डा अभिव्यक्ति के रूप में इस का उपयोग कर सकते हैं:

try 
    { 
     //..... 
    } 
    catch (Exception ex) 
    { 
     Action<Exception> lambda; 

     lambda = async (x) => 
     { 
      // await (...); 
     }; 

     lambda(ex); 
    } 
+0

यह लैम्ब्डा 'एसिंक शून्य' बनाता है, जिसका उपयोग नहीं किया जाना चाहिए, जब तक आपको यह नहीं करना चाहिए। – svick

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