ক্যাপ ব্লকে অপেক্ষা করুন


85

আমার কাছে নিম্নলিখিত কোড রয়েছে:

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

মূলত আমি কোনও ইউআরএল থেকে ডাউনলোড করতে চাই এবং যখন এটি ব্যতিক্রম হয় তখন আমি অন্য ইউআরএল থেকে ডাউনলোড করতে চাই। উভয় সময় অবশ্যই async। তবে কোডটি সংকলন করে না, কারণ

ত্রুটি CS1985: ক্যাচ ক্লজের মূল অংশে অপেক্ষা করতে পারে না

ঠিক আছে, যে কোনও কারণে এটি নিষিদ্ধ তবে এখানে সঠিক কোড প্যাটার্নটি কী?

সম্পাদনা:

সুসংবাদটি হ'ল সি # 6.0 সম্ভবত ক্যাচ এবং অবশেষে উভয় ব্লক উভয় কলকে অপেক্ষা করতে অনুমতি দেবে

উত্তর:


103

আপডেট: সি # 6.0 ক্যাচ প্রতীক্ষিত সমর্থন করে


পুরানো উত্তর : একটি পতাকা ব্যবহার awaitকরে 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
ধন্যবাদ সোভিক, এটি বেশ সুস্পষ্ট, এর চেয়ে আরও ভাল কিছু, আরও বেশি সংযুক্তি হিসাবে সংযুক্ত?
গিরিগিরি বালসি

আমি মনে করি না এর মতো কিছু আছে।
সুইভ

4
আপনার ক্ষেত্রে, আপনি টাস্কের ধারাবাহিকতাও ব্যবহার করতে পারেন। তবে svickএর উত্তরের কোডটি ধারাবাহিকতা ব্যবহার করে কোডের চেয়ে পরিষ্কার।
স্টিফেন ক্লিয়ারি

16
এমনকি যদি কলস্ট্যাকটি না ছাড়িয়েও আপনাকে ব্যতিক্রমটি পুনর্বিবেচনার প্রয়োজন হয়, আপনি System.Runtime.ExceptionServices.ExceptionDispatchInfoস্থির শ্রেণিটিও ব্যবহার করতে পারেন । কেবল ExceptionDispatchInfo.Capture(ex)আপনার ক্যাচ ব্লকে কল করুন এবং স্থানীয় ভেরিয়েবলে রিটার্ন মান, ক্যাপচার হওয়া ব্যতিক্রম সংরক্ষণ করুন। একবার আপনার অ্যাসিঙ্ক কোডটি সম্পন্ন করার পরে আপনি ব্যবহার করতে পারেন capturedException.Throw()যা মূল ব্যতিক্রমটিকে সঠিকভাবে পুনর্বিবেচনা করবে।
এটিয়েন মাহু

দুর্দান্ত কৌশল
জিয়া উর রহমান

24

এখানে প্রদর্শিত রোজলিনের শেষ ব্যবহারকারীর পূর্বরূপ হিসাবে ক্যাচ ব্লকে অপেক্ষা করা এখন সম্ভব (ক্যাচ / অবশেষে ওয়েভের অধীনে তালিকাভুক্ত) এবং সি # 6 এ অন্তর্ভুক্ত থাকবে।

তালিকাভুক্ত উদাহরণটি হ'ল

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

আপডেট: আরও নতুন লিঙ্ক যুক্ত হয়েছে এবং এটি সি # 6 এ থাকবে


9

এটি কাজ করে বলে মনে হচ্ছে।

        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;

6

একবার চেষ্টা করে দেখুন:

         try
        {
            await AsyncFunction(...);
        }

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

( Wait()শেষ দেখুন )



1

ফ্যালব্যাক টাস্কটির অপেক্ষার পরে আমি যে প্যাটার্নটিটি ব্যতিক্রমটি পুনরায় ছড়িয়ে দিতে ব্যবহার করি:

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

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

1

আপনি নীচে ল্যাম্বডা এক্সপ্রেশন ব্যবহার করতে পারেন:

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

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

        lambda(ex);
    }

এটি ল্যাম্বডাকে তোলে async void, যা ব্যবহার করা উচিত নয়, যদি না আপনার প্রয়োজন হয়।
সোভিক

0

আপনি awaitক্যাচ ব্লকের পরে ক labelএবং তার পরে একটি gotoব্লক রেখে দিতে পারেন। (না, সত্যিই! গোটো খুব খারাপ নয়!)


0

অনুরূপ উদাহরণস্বরূপ, আমি একটি ক্যাচ ব্লকে অপেক্ষা করতে অক্ষম। তবে, আমি একটি পতাকা সেট করতে সক্ষম হয়েছি, এবং যদি একটি বিবৃতিতে পতাকাটি ব্যবহার করতে পারি (নীচের কোড)

---------------------------------------...

boolean exceptionFlag = false; 

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

if(exceptionFlag == true){ 
do what you wanted to do in the catch block 
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.