ক্যাচ ব্লক থেকে ব্যতিক্রম ছুঁড়ে ফেললে শেষ পর্যন্ত কখন চালানো হবে?


134
try {
   // Do stuff
}
catch (Exception e) {
   throw;
}
finally {
   // Clean up
}

উপরের ব্লকে শেষ অবধি কবে বলা হয়? ই ছুঁড়ে ফেলার আগে বা শেষ পর্যন্ত বলা হয় এবং তারপর ধরা হয়?


14
PS আপনার "নিক্ষেপ ই;" করা উচিত নয়; কারণ এটি মূল ব্যতিক্রমের স্ট্যাক ট্রেসকে বিশৃঙ্খলা করবে। আপনার কেবল "নিক্ষেপ;" করা উচিত। অথবা একটি নতুন ব্যতিক্রম তৈরি করুন এবং এটি ছোঁড়ার আগেই অভ্যন্তরীণ ধারণাটি "ই" তে সেট করুন।
এরভ ওয়াল্টার

24
শেষ অবধি কীওয়ার্ডটির একটি দরিদ্র পছন্দ হবে যদি এটি শেষ না চলে , আপনি কি বলবেন না?
এরিক লিপার্ট

@ এরভওয়াল্টার এখনও কি সত্য? আমি এটি ভিএস2017 এ উভয় উপায়েই পরীক্ষা করে দেখছি এবং এটি দেখতে একরকম দেখা যাচ্ছে। আপনি আরও কিছু তথ্য বা একটি রেফারেন্স সরবরাহ করতে পারেন? ধন্যবাদ
জেফ

শুধু নামকরণ পরামর্শ ব্যবহার ব্যতিক্রম প্রাক্তন - রিজার্ভ ই ইভেন্ট / প্রতিনিধিদের জন্য
এমআর আর

উত্তর:


137

পুনরায় নিক্ষেপ করার পরে এটি ডাকা হবে (অর্থাত ব্লক কার্যকর করার পরে)

7 বছর পরে এটি সম্পাদনা - একটি গুরুত্বপূর্ণ দ্রষ্টব্য হ'ল যদি eকল স্ট্যাকের উপরে যদি চেষ্টা / ক্যাচ ব্লক ধরে না যায় বা কোনও বিশ্বব্যাপী ব্যতিক্রম হ্যান্ডলার দ্বারা পরিচালিত না হয় তবে finallyব্লকটি কখনই কার্যকর হতে পারে না।


18
এবং যদি আপনি এনভ্রিয়মেন্টমেন্ট কল করেন না Fফেইলফাস্ট ()
জোহানেস রুডল্ফ

16
ব্র্যান্ডনের উত্তরে কোড চেষ্টা করার পরে, আমি দেখতে পাচ্ছি যে finallyপূর্ববর্তীটিতে ফেলে দেওয়া ব্যতিক্রমটি catchকখনই বাইরের - ব্লকে ধরা না পড়লে তা কার্যকর করা হয় না ! trycatch
অ্যান্ড্রু

3
নতুন তথ্য অন্তর্ভুক্ত করার জন্য আপনার (গৃহীত) উত্তর সম্পাদনার জন্য ধন্যবাদ।
গর্ডন বিন

3
তারা (মাইক্রোসফ্ট) নতুন ডকুমেন্টেশন সাইটে এটি সম্পর্কে কথা বলছে: ডকস.মাইক্রোসফট.ইন / ডটনেট / সিএসআরপি / ল্যাঙ্গুয়েজ-রেফারেন্স /… : "একটি হ্যান্ডেল ব্যতিক্রমের মধ্যে, শেষ অবধি ব্লকটি চালানোর নিশ্চয়তা দেওয়া হয়েছে। তবে , যদি ব্যতিক্রমটি হ্যান্ডেল না করা হয়, অবশেষে ব্লকটির সম্পাদন নির্ভর করে কীভাবে ব্যতিক্রম আনওয়াইন্ড অপারেশনটি ট্রিগার করা হয় তার উপর নির্ভর করে That
ডটনেটস্পার্কি

1
নোট করুন যে "কল স্ট্যাকের উপরে আরও একবার চেষ্টা / ক্যাচ ব্লকের দ্বারা ধরা" এএসপি.এনইটি বা একটি পরীক্ষক রানার মতো ফ্রেমওয়ার্ক হ্যান্ডলারগুলিকে অন্তর্ভুক্ত করবে। এটি দেওয়ার আরও ভাল উপায় হতে পারে "যদি আপনার প্রোগ্রামটি ক্যাচ ব্লকের পরে চালিয়ে যেতে থাকে তবে অবশেষে ব্লকটি কার্যকর হবে।"
অ্যারোক্যাস

90

কেন চেষ্টা করবেন না:

outer try
inner try
inner catch
inner finally
outer catch
outer finally

কোড সহ (উল্লম্ব স্থানের জন্য ফর্ম্যাট করা):

static void Main() {
    try {
        Console.WriteLine("outer try");
        DoIt();
    } catch {
        Console.WriteLine("outer catch");
        // swallow
    } finally {
        Console.WriteLine("outer finally");
    }
}
static void DoIt() {
    try {
        Console.WriteLine("inner try");
        int i = 0;
        Console.WriteLine(12 / i); // oops
    } catch (Exception e) {
        Console.WriteLine("inner catch");
        throw e; // or "throw", or "throw anything"
    } finally {
        Console.WriteLine("inner finally");
    }
}

5
+1, এত সাধারণ কোনও কিছুর জন্য, আপনার কাছে মার্কের মতোই চেষ্টা করা উচিত। জিজে নেস্টেড ট্রাই / ক্যাচ / অবশেষে :) এর মাধ্যমে এটি চিত্রিত করেছেন
অ্যালেন রাইস

1
@ অ্যালানরাইস কেন এটি চেষ্টা করে দেখুন যদি মার্ক ইতিমধ্যে আছে, এবং আমি কেবল গুগল করতে পারি মার্কের উত্তর খুঁজে পেতে? বা সম্ভবত আরও ভাল, নিজেকে চেষ্টা করুন, তারপরে একটি এসও প্রশ্ন তৈরি করুন এবং অন্যের উপকারের জন্য নিজের উত্তর দিন।
জোশডেন

8
দয়া করে মনে রাখবেন আপনি যদি বাইরের ক্যাচে ব্যতিক্রম না ধরেন তবে শেষ পর্যন্ত অভ্যন্তরীণটি কখনও কার্যকর হয় না !! সেক্ষেত্রে আউটপুটটি হলouter try inner try inner catch Unhandled Exception: System.DivideByZeroException...
অ্যান্ড্রু

1
@ এন্ড্রু আপনি ঠিক বলেছেন। এমএসডিএন ম্যাগাজিন ২০০৮ এর সেপ্টেম্বর: ব্যাখ্যাটি আপনি এখানে পেতে পারেন : সিএলআর-এ আনহানডেল ব্যতিক্রম প্রক্রিয়াজাতকরণ (সিএমআর খোলার জন্য এটি আনলক করা দরকার: ফাইলের বৈশিষ্ট্য -> সাধারণ -> আনলক)। যদি আপনি বাইরের ক্যাচ ব্লকটিকে "ক্যাচ (আর্গুমেন্টএক্সেপশন)" দিয়ে প্রতিস্থাপন করেন তবে অবশেষে কারও ব্লকটি আর চালানো হবে না, কারণ সিএলআর "ডিভাইডবিজারো এক্সেকশন" ব্যতিক্রমটি হ্যান্ডেল করতে সম্মত এমন কোনও ব্যতিক্রম হ্যান্ডলার খুঁজে পাবে না।
ভ্লাদিমির

35

এখানে সমস্ত উত্তর পড়ার পরে মনে হচ্ছে চূড়ান্ত উত্তরটি এটি নির্ভর করে :

  • আপনি যদি ক্যাচ ব্লকের মধ্যে কোনও ব্যতিক্রম পুনরায় নিক্ষেপ করেন এবং সেই ব্যতিক্রমটি অন্য ক্যাচ ব্লকের ভিতরে ধরা পড়ে, ডকুমেন্টেশন অনুসারে সবকিছু কার্যকর হয়।

  • যাইহোক, যদি পুনরায় ট্রাউন ব্যতিক্রমটি নিয়ন্ত্রণহীন হয়, শেষ পর্যন্ত কখনই কার্যকর করে না।

আমি ভিএস2010 ডাব্লু / সি # 4.0 এ এই কোড নমুনাটি পরীক্ষা করেছি

static void Main()
    {
        Console.WriteLine("Example 1: re-throw inside of another try block:");

        try
        {
            Console.WriteLine("--outer try");
            try
            {
                Console.WriteLine("----inner try");
                throw new Exception();
            }
            catch
            {
                Console.WriteLine("----inner catch");
                throw;
            }
            finally
            {
                Console.WriteLine("----inner finally");
            }
        }
        catch
        {
            Console.WriteLine("--outer catch");
            // swallow
        }
        finally
        {
            Console.WriteLine("--outer finally");
        }
        Console.WriteLine("Huzzah!");

        Console.WriteLine();
        Console.WriteLine("Example 2: re-throw outside of another try block:");
        try
        {
            Console.WriteLine("--try");
            throw new Exception();
        }
        catch
        {
            Console.WriteLine("--catch");
            throw;
        }
        finally
        {
            Console.WriteLine("--finally");
        }

        Console.ReadLine();
    }

এখানে ফলাফল:

উদাহরণ 1: আরেকটি চেষ্টা ব্লকের ভিতরে পুনরায় নিক্ষেপ করুন: -
আউটর চেষ্টা
---- অভ্যন্তরীণ চেষ্টা
---- অভ্যন্তরীণ ক্যাচ
---- অভ্যন্তরীণ -
আউটার ক্যাচ -
আউট অব হুজাহ
!

উদাহরণ 2: আরেকটি চেষ্টা ব্লকের বাইরে পুনরায় নিক্ষেপ করুন:
--ট্রি -
ক্যাচ

আনহ্যান্ডলড ব্যতিক্রম: সিস্টেম. এক্সেপশন: 'সিস্টেম. এক্সপ্লেশন' টাইপের ব্যতিক্রম ছুঁড়ে দেওয়া হয়েছিল।
কনসোল অ্যাপ্লিকেশন ১. প্রোগ্রামে.মেন () সি তে: \ স্থানীয় উত্স so কনসোল অ্যাপ্লিকেশন 1 \ প্রোগ্রাম.cs: লাইন 53


3
দুর্দান্ত ধরা, আমি সে সম্পর্কে অবগত ছিলাম না!
অ্যান্ড্রু

1
নোট করুন যে শেষটি শেষ পর্যন্ত চালাতে পারে, আপনি যা পছন্দ করেছেন তার উপর নির্ভর করে: stackoverflow.com/a/46267841/480982
টমাস ওয়েলার

1
আকর্ষণীয় ... .NET কোর 2.0 তে, অবশেষে অংশটি নিরবচ্ছিন্ন ব্যতিক্রমের পরে চলে।
মাহদী গিয়াসি

আকর্ষণীয়ভাবে যথেষ্ট, আমি সবেমাত্র .NET কোর 2.0 এবং .NET ফ্রেমওয়ার্ক 4.6.1 উভয়টিতে একটি পরীক্ষা করেছি এবং তারা উভয়ই অবশেষে চালিত ব্যর্থতার পরে চালায়। এই আচরণের পরিবর্তন হয়েছে?
ক্যামেরন বিয়েলস্টাইন

24

আপনার উদাহরণটি এই কোডটির সাথে অভিন্ন আচরণ করবে:

try {
    try {
        // Do stuff
    } catch(Exception e) {
        throw e;
    }
} finally {
    // Clean up
}

পার্শ্ব নোট হিসাবে, যদি আপনি সত্যিই বোঝাতে চান throw e;(এটি হ'ল একই ব্যতিক্রমটিকে আপনি ফেলেছিলেন) তবে এটি করা আরও ভাল throw;কারণ এটি একটি নতুন তৈরি করার পরিবর্তে মূল স্ট্যাক ট্রেসকে সংরক্ষণ করবে।


আমি এটি সঠিক মনে করি না। শেষ পর্যন্ত বাইরের চেষ্টা ব্লকের ভিতরে থাকা উচিত এটির বাইরে নয়
ম্যাথু পিগ্রাম

@ ম্যাথিউপিগ্রাম: আপনার অর্থ কী? finallyব্লক আসলে পর চালানো হবে catchব্লক (এমনকি যদি ধরা ব্লক ব্যতিক্রম rethrows), যা কি আমার স্নিপেট চিত্রিত করার চেষ্টা করছে।
ড্যানিয়েল প্রাইডেন

আমি তার উদাহরণটি কীভাবে ব্যাখ্যা করি তা থেকে তিনি শেষ পর্যন্ত অন্য চেষ্টা ব্লকের মধ্যে চেষ্টা করার চেষ্টা করছেন। অবশেষে চেষ্টা করে দেখার চেষ্টা নয়
ম্যাথু পিগ্রাম

1
@ ম্যাথিউপিগ্রাম: আমার উত্তরের কোনও "ট্রাই-ক্যাচ-অবশেষে" নির্মাণের দরকার নেই। এটির একটি "চেষ্টা-অবশেষে" রয়েছে এবং এর tryউত্তরটির ভিতরে আমার উত্তরে একটি "চেষ্টা-ধরা" রয়েছে। আমি দুটি 2-পার্ট কনস্ট্রাক্ট ব্যবহার করে 3-পার্ট কনস্ট্রাক্টের আচরণটি ব্যাখ্যা করার চেষ্টা করছি। আমি tryআসল প্রশ্নে দ্বিতীয় ব্লকের কোনও চিহ্ন দেখতে পাচ্ছি না , সুতরাং আপনি কোথায় পাচ্ছেন তা বুঝতে পারছি না।
ড্যানিয়েল প্রাইডেন

12

যদি ক্যাচ হ্যান্ডলার ব্লকের ভিতরে কোনও অপরিবর্তিত ব্যতিক্রম থাকে তবে শেষ অবধি ঠিক শূন্য বার বলা হয়ে থাকে

  static void Main(string[] args)
  {
     try
     {
        Console.WriteLine("in the try");
        int d = 0;
        int k = 0 / d;
     }
     catch (Exception e)
     {
        Console.WriteLine("in the catch");
        throw;
     }
     finally
     {
        Console.WriteLine("In the finally");
     }
  }

আউটপুট:

সি: \ ব্যবহারকারী \ প্রশাসক \ নথি \ TestExceptionNesting \ বিন \ রিলিজ> TestExceptionNesting.exe

চেষ্টা করে

ধরতে

আনহ্যান্ডলড ব্যতিক্রম: সিস্টেম.ডাইভাইডবিজিরো এক্সেপশন: শূন্য দ্বারা ভাগ করার চেষ্টা করা হয়েছে। টেস্টএক্সেপশন নেস্টিং.পাগ্রাম.মেন (স্ট্রিং [] আরগস) এ সি: \ ব্যবহারকারী \ প্রশাসক \ নথি \ টেস্টএক্সেপশন নেস্টিং \ টেস্টএক্সেপশন নেস্টিং.সি: লাইন 22

সি: \ ব্যবহারকারী \ প্রশাসক \ নথি \ TestExceptionNesting \ বিন \ মুক্তি>

আমি আজ একটি সাক্ষাত্কারে এই প্রশ্নটি জিজ্ঞাসা করেছি এবং সাক্ষাত্কারকারীর ফিরে যেতে থাকল "আপনি কি শেষ অবধি ডাকেন না নিশ্চিত?" আমি অনিশ্চিত ছিলাম যদি এটি কোনও কৌতুকপূর্ণ প্রশ্ন ছিল বা সাক্ষাত্কারকারীর মনে অন্য কিছু ছিল এবং আমার ডিবাগ করার জন্য ভুল কোড লিখেছিল তাই আমি বাড়িতে এসে চেষ্টা করেছিলাম (বিল্ড এবং রান করুন, কোনও ডিবাগার ইন্টারঅ্যাকশন নয়), কেবল আমার মনকে লক্ষ্য রাখার জন্য বিশ্রাম.


যদি ছুঁড়ে দেওয়া ব্যতিক্রম স্ট্যাকের অন্য কোথাও ধরে না যায়, তবে যদি সেই ছোঁড়া ব্যতিক্রমটি পরিচালনা করা হয় তবে এটি কার্যকর করতে পারে ... বা আমি ভুল হতে পারি ...
টমোসিয়াস

@ টমোসিয়াস, হ্যাঁ, এটিই ব্র্যান্ডনের উত্তর ব্যাখ্যা করে। :)
অ্যান্ড্রু

@ টোমোসিয়াস সেজন্য আমি "যদি কোনও হাতছাড়া ব্যতিক্রম থাকে তবে" উল্লেখ করে শুরু করেছি। যদি ফেলে দেওয়া ব্যতিক্রমটি কোথাও ধরা পড়ে তবে সংজ্ঞা অনুসারে আমরা একটি আলাদা কেস নিয়ে কথা বলছি।
ইউসেবিও রুফিয়ান-জিলবারম্যান

এটি সত্য নয়। কমপক্ষে নেট কোর 3.1 এর জন্য নয়। এই কোড সহ একটি সাধারণ নতুন কনসোল প্রকল্প ব্যতিক্রমের পরে "শেষ পর্যন্ত" দেখায়।
এমজারো

আচরণটি পরিবর্তিত হয়েছে বলে আকর্ষণীয়, আমি পোস্ট করার সময় নেট কোর এমনকি উপস্থিত ছিল না;)
ইউসেবিও রুফিয়ান-জিলবারম্যান

2

এটিরও জানার একটি সহজ উপায় হ'ল আপনার কোডটি ডিবাগ করা এবং অবশেষে কখন ডাকা হবে তা বিজ্ঞপ্তি।


1

একটি সি # কনসোল অ্যাপ্লিকেশন দিয়ে পরীক্ষা করা, অবশেষে কোডটি ব্যতিক্রম ছড়িয়ে দেওয়ার পরে কার্যকর করা হয়েছে: "অ্যাপ্লিকেশন ত্রুটি ডায়ালগ" বিদ্যমান ছিল এবং আপনি "প্রোগ্রামটি বন্ধ করুন" বিকল্পটি বেছে নেওয়ার পরে, শেষ অবধি সেই কনসোল উইন্ডোটিতে কার্যকর করা হয়েছিল। তবে শেষ অবধি কোড ব্লকের ভিতরে ব্রেকিং পয়েন্ট স্থাপন করে আমি কখনই এটি আঘাত করতে পারি না। ডিবাগারটি থ্রো স্টেটমেন্টে থামতে থাকে। আমার পরীক্ষার কোডটি এখানে:

    class Program
    {
       static void Main(string[] args)
       {
          string msg;
          Console.WriteLine(string.Format("GetRandomNuber returned: {0}{1}", GetRandomNumber(out msg), msg) == "" ? "" : "An error has occurred: " + msg);
       }

       static int GetRandomNumber(out string errorMessage)
       {
         int result = 0;
         try
         {
            errorMessage = "";
            int test = 0;
            result = 3/test;
            return result;
         }
         catch (Exception ex)
         {
            errorMessage = ex.Message;
            throw ex;

         }
         finally
         {
            Console.WriteLine("finally block!");
         }

       }
    }

ভিএস2010 -। নেট ফ্রেমওয়ার্ক 4.0 এ ডিবাগিং

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.