কনসোল অ্যাপ্লিকেশন .NET গ্লোবাল ব্যতিক্রম হ্যান্ডলার


198

প্রশ্ন: আমি আমার কনসোল অ্যাপ্লিকেশনটিতে হাতছাড়া হওয়া ব্যতিক্রমগুলির জন্য একটি গ্লোবাল ব্যতিক্রম হ্যান্ডলারটি সংজ্ঞায়িত করতে চাই। এসপ নেটনে, গ্লোবাল.এক্সএক্স এবং উইন্ডো অ্যাপ্লিকেশন / পরিষেবাগুলিতে একটি নীচের মতো সংজ্ঞা দিতে পারে one

AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyExceptionHandler);

তবে আমি কীভাবে কনসোল অ্যাপ্লিকেশনটির জন্য একটি গ্লোবাল ব্যতিক্রম হ্যান্ডলার সংজ্ঞায়িত করতে পারি?
কারেন্টডোমাইন মনে হচ্ছে (.NET 2.0) কাজ করছে না?

সম্পাদনা:

আরগ, বোকা ভুল।
VB.NET- এ কারেন্টডোমেনের সামনে "অ্যাডহ্যান্ডলার" কীওয়ার্ড যুক্ত করা দরকার, অন্যথায় ইন্টেলিসেন্সে আনহানডেলড এক্সপশন ইভেন্টটি দেখতে পাচ্ছে না ...
কারণ ভিবি.এনইটি এবং সি # সংকলক ইভেন্টটিকে হ্যান্ডলিংয়ের সাথে আলাদাভাবে আচরণ করে।

উত্তর:


283

না, এটি করার সঠিক উপায়। এটি ঠিক যেমনটি করা উচিত ঠিক তেমন কাজ করেছে, এমন কিছু থেকে আপনি সম্ভবত কাজ করতে পারেন:

using System;

class Program {
    static void Main(string[] args) {
        System.AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionTrapper;
        throw new Exception("Kaboom");
    }

    static void UnhandledExceptionTrapper(object sender, UnhandledExceptionEventArgs e) {
        Console.WriteLine(e.ExceptionObject.ToString());
        Console.WriteLine("Press Enter to continue");
        Console.ReadLine();
        Environment.Exit(1);
    }
}

মনে রাখবেন যে আপনি এইভাবে জিটার দ্বারা উত্পাদিত টাইপ এবং ফাইল লোড ব্যতিক্রমগুলি ধরতে পারবেন না। আপনার মেইন () পদ্ধতিটি চলমান শুরু হওয়ার আগে এগুলি ঘটে। এগুলি ধরার জন্য জিটটারে বিলম্ব হওয়া প্রয়োজন, ঝুঁকিপূর্ণ কোডটি অন্য কোনও পদ্ধতিতে সরান এবং এর সাথে [মেথডিম্পল (মেথিডিম্পলপশনস.নোইনলাইনিং)] বৈশিষ্ট্য প্রয়োগ করুন।


3
আপনি এখানে প্রস্তাবিত যা প্রয়োগ করেছি আমি তা প্রয়োগ করেছি, তবে আমি অ্যাপ্লিকেশনটি থেকে বেরিয়ে আসতে চাই না। আমি এটা লগ ইন করুন, এবং প্রক্রিয়া (ছাড়া চালিয়ে যেতে চান Console.ReadLine()বা প্রোগ্রাম প্রবাহ অন্য কোন ঝামেলা কিন্তু কি আমি পেতে ব্যতিক্রম আবার এবং আবার পুনরায় উত্থাপন, এবং আবার

3
@ শাহরুজ জেফরি: আপনি একবারে নিয়ন্ত্রণহীন ব্যতিক্রম পেলে আপনি চালিয়ে যেতে পারবেন না। স্ট্যাকটি বিশৃঙ্খলাবদ্ধ এবং এটি টার্মিনাল। আপনার যদি কোনও সার্ভার থাকে তবে আপনি আনহ্যান্ডলেড এক্সসেপশনট্রেপারে যা করতে পারেন তা একই কমান্ড লাইনের যুক্তি দিয়ে প্রোগ্রামটি পুনরায় চালু করা হবে।
স্টিফান স্টেইগার

6
এটা অবশ্যই! আমরা এখানে অ্যাপ্লিকেশন.ট্রেডএক্সসেপশন ইভেন্টের কথা বলছি না।
হ্যান্স প্যাস্যান্ট

4
আমি মনে করি এই উত্তরটি এবং উত্তরগুলিতে দেওয়া মন্তব্যগুলি বোঝার মূল চাবিকাঠিটি অনুধাবন করা যে এই কোডটি ব্যতিক্রম সনাক্ত করতে এখন প্রদর্শিত হয়েছে, তবে এটি সম্পূর্ণরূপে "হ্যান্ডেল" করবে না কারণ আপনি চালিয়ে যাওয়ার অপশন থাকতে পারে এমন কোনও সাধারণ চেষ্টা / ক্যাপ ব্লক হিসাবেই থাকতে পারেন । বিশদ জন্য আমার অন্যান্য উত্তর দেখুন। আপনি যদি এইভাবে ব্যতিক্রমটিকে "পরিচালনা" করেন তবে অন্য থ্রেডে ব্যতিক্রম ঘটলে আপনার চলমান চালিয়ে যাওয়ার কোনও বিকল্প নেই। সেই অর্থে, এটি বলা যেতে পারে যে এই উত্তরটি ব্যতিক্রমটিকে পুরোপুরি "হ্যান্ডেল" করে না যদি "হ্যান্ডেল" দ্বারা আপনি "প্রক্রিয়াটি চালিয়ে যান এবং চালিয়ে যান" mean
ব্লুমোনকএমএন

4
বিভিন্ন থ্রেডে চালানোর জন্য প্রচুর প্রযুক্তি রয়েছে তা উল্লেখ করার দরকার নেই। উদাহরণস্বরূপ, টাস্ক প্যারালাল লাইব্রেরি (টিপিএল) আনহ্যান্ডেল ব্যতিক্রমগুলি ধরার নিজস্ব উপায় রয়েছে। সুতরাং, এটি সমস্ত পরিস্থিতির জন্য কাজ করে না বলা একরকম হাস্যকর বিষয়, সি # তে সমস্ত কিছুর জন্য একটিও জায়গা নেই, তবে আপনি যে প্রযুক্তি ব্যবহার করেন তার উপর নির্ভর করে আপনি বিভিন্ন জায়গায় প্রবেশ করতে পারেন।
ডগ

23

যদি আপনার একক থ্রেডযুক্ত অ্যাপ্লিকেশন থাকে তবে আপনি মেইন ফাংশনে একটি সাধারণ চেষ্টা / ক্যাপ ব্যবহার করতে পারেন, তবে এটি মেইন ফাংশনের বাইরে ফেলে দেওয়া হতে পারে এমন ব্যতিক্রমগুলি কভার করে না, অন্য থ্রেডগুলিতে, উদাহরণস্বরূপ (অন্য হিসাবে উল্লিখিত হিসাবে মন্তব্য)। এই কোডটি প্রদর্শন করে যে কীভাবে কোনও ব্যতিক্রম অ্যাপ্লিকেশনটিকে মীমাংসিত করার চেষ্টা করলেও অ্যাপ্লিকেশনটি বন্ধ হতে পারে (লক্ষ্য করুন আপনি কীভাবে প্রোগ্রামটি সুনির্দিষ্টভাবে প্রস্থান করেন যদি আপনি চাপটি চাপান এবং যদি ব্যতিক্রম হওয়ার আগে অ্যাপ্লিকেশনটিকে দক্ষতার সাথে প্রস্থান করতে দেয় তবে আপনি যদি এটি চালাতে দেন তবে , এটি বেশ দুর্ভাগ্যজনকভাবে শেষ করে):

static bool exiting = false;

static void Main(string[] args)
{
   try
   {
      System.Threading.Thread demo = new System.Threading.Thread(DemoThread);
      demo.Start();
      Console.ReadLine();
      exiting = true;
   }
   catch (Exception ex)
   {
      Console.WriteLine("Caught an exception");
   }
}

static void DemoThread()
{
   for(int i = 5; i >= 0; i--)
   {
      Console.Write("24/{0} =", i);
      Console.Out.Flush();
      Console.WriteLine("{0}", 24 / i);
      System.Threading.Thread.Sleep(1000);
      if (exiting) return;
   }
}

অ্যাপ্লিকেশনটি প্রস্থান হওয়ার আগে যখন অন্য থ্রেড কিছু পরিষ্কার করার জন্য ব্যতিক্রম ছুঁড়েছে তার আপনি বিজ্ঞপ্তি পেতে পারেন, তবে যতদূর আমি বলতে পারি, আপনি কনসোল অ্যাপ্লিকেশন থেকে অ্যাপ্লিকেশনটি চালিয়ে যেতে বাধ্য করতে পারবেন না যদি আপনি ব্যতিক্রমটি পরিচালনা না করেন তবে যে থ্রেড থেকে এটি অ্যাপ্লিকেশনটিকে এমনভাবে আচরণ করার জন্য কিছু অস্পষ্ট সামঞ্জস্যতার বিকল্পগুলি ব্যবহার না করে ছুঁড়ে ফেলা হয় x নেট 1.x. এই কোডটি প্রদর্শন করে যে কীভাবে মূল থ্রেডটি অন্য থ্রেড থেকে আসা ব্যতিক্রম সম্পর্কে অবহিত করা যেতে পারে তবে তবুও অসুখীভাবে শেষ হবে:

static bool exiting = false;

static void Main(string[] args)
{
   try
   {
      System.Threading.Thread demo = new System.Threading.Thread(DemoThread);
      AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
      demo.Start();
      Console.ReadLine();
      exiting = true;
   }
   catch (Exception ex)
   {
      Console.WriteLine("Caught an exception");
   }
}

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
   Console.WriteLine("Notified of a thread exception... application is terminating.");
}

static void DemoThread()
{
   for(int i = 5; i >= 0; i--)
   {
      Console.Write("24/{0} =", i);
      Console.Out.Flush();
      Console.WriteLine("{0}", 24 / i);
      System.Threading.Thread.Sleep(1000);
      if (exiting) return;
   }
}

সুতরাং আমার মতে, কনসোল অ্যাপ্লিকেশনটিতে এটিকে হ্যান্ডেল করার সর্বোত্তম উপায় হ'ল প্রতিটি স্তরের মূল স্তরে ব্যতিক্রম হ্যান্ডলার রয়েছে তা নিশ্চিত করা:

static bool exiting = false;

static void Main(string[] args)
{
   try
   {
      System.Threading.Thread demo = new System.Threading.Thread(DemoThread);
      demo.Start();
      Console.ReadLine();
      exiting = true;
   }
   catch (Exception ex)
   {
      Console.WriteLine("Caught an exception");
   }
}

static void DemoThread()
{
   try
   {
      for (int i = 5; i >= 0; i--)
      {
         Console.Write("24/{0} =", i);
         Console.Out.Flush();
         Console.WriteLine("{0}", 24 / i);
         System.Threading.Thread.Sleep(1000);
         if (exiting) return;
      }
   }
   catch (Exception ex)
   {
      Console.WriteLine("Caught an exception on the other thread");
   }
}

অপ্রত্যাশিত ত্রুটির জন্য
ট্র্যাক

12

থ্রেড থেকে আপনার ব্যতিক্রমগুলিও পরিচালনা করতে হবে:

static void Main(string[] args) {
Application.ThreadException += MYThreadHandler;
}

private void MYThreadHandler(object sender, Threading.ThreadExceptionEventArgs e)
{
    Console.WriteLine(e.Exception.StackTrace);
}

ওহ, দুঃখিত যে উইনফর্মগুলির জন্য ছিল, যে কোনও থ্রেডের জন্য আপনি কোন কনসোল অ্যাপ্লিকেশন ব্যবহার করছেন সে জন্য আপনাকে চেষ্টা / ক্যাচ ব্লকে আবদ্ধ করতে হবে। ব্যাকগ্রাউন্ড থ্রেডগুলি যা অবিচ্ছিন্ন ব্যতিক্রমগুলির মুখোমুখি হয় অ্যাপ্লিকেশনটি শেষ হওয়ার কারণ নয়।


1

আমি সবেমাত্র একটি পুরানো ভিবি.এনইটি কনসোল অ্যাপ্লিকেশন উত্তরাধিকার সূত্রে পেয়েছি এবং একটি গ্লোবাল এক্সসেপশন হ্যান্ডলার সেটআপ করা দরকার। যেহেতু এই প্রশ্নটি কয়েকবার VB.NET উল্লেখ করেছে এবং VB.NET এর সাথে ট্যাগ করা আছে, তবে এখানে অন্যান্য সমস্ত উত্তর সি # তে রয়েছে, আমি ভেবেছিলাম আমিও একটি ভিবি.এনইটি অ্যাপ্লিকেশনটির জন্য সঠিক বাক্য গঠন করব।

Public Sub Main()
    REM Set up Global Unhandled Exception Handler.
    AddHandler System.AppDomain.CurrentDomain.UnhandledException, AddressOf MyUnhandledExceptionEvent

    REM Do other stuff
End Sub

Public Sub MyUnhandledExceptionEvent(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs)
    REM Log Exception here and do whatever else is needed
End Sub

আমি REMএখানে একক উদ্ধৃতির পরিবর্তে মন্তব্য চিহ্নিতকারী ব্যবহার করেছি কারণ স্ট্যাক ওভারফ্লো মনে হচ্ছে সিনট্যাক্সটি আরও ভালভাবে হাইলাইট করেছে REM


-13

আপনি যা চেষ্টা করছেন তা এমএসডিএন ডকের। নেট 2.0 এর জন্য কাজ করা উচিত। কনসোল অ্যাপ্লিকেশনটির জন্য আপনার প্রবেশ পয়েন্টের আশেপাশে আপনি মূল চেষ্টা করতে / ধরতে চেষ্টা করতে পারেন।

static void Main(string[] args)
{
    try
    {
        // Start Working
    }
    catch (Exception ex)
    {
        // Output/Log Exception
    }
    finally
    {
        // Clean Up If Needed
    }
}

এবং এখন আপনার ক্যাচ ধরা পড়েনি এমন কোনও কিছুই হ্যান্ডেল করবে ( মূল থ্রেডে )। এটি দুর্দান্ত এবং এমনকি যদি আপনি চান তবে যেখানে এটি পুনরায় চালু হতে পারে, বা আপনি অ্যাপ্লিকেশনটিকে মরাতে এবং ব্যতিক্রমটি লগ করতে পারেন। আপনি কোনও ক্লিন আপ করতে চাইলে আপনি শেষ পর্যন্ত যুক্ত করবেন। প্রতিটি থ্রেডের নিজস্ব মতো উচ্চ স্তরের ব্যতিক্রম হ্যান্ডলিংয়ের প্রয়োজন হবে।

ব্লুমনকএমএন দ্বারা নির্দেশিত থ্রেডগুলি সম্পর্কে পয়েন্টটি স্পষ্ট করতে সম্পাদিত এবং তার উত্তরে বিস্তারিতভাবে দেখানো হয়েছে।


1
দুর্ভাগ্যক্রমে, ব্যতিক্রমগুলি এখনও মূল () ব্লকের বাইরে ফেলে দেওয়া যেতে পারে। এটি আসলে আপনার মত ভাবার মতো "সমস্ত ক্যাচ করুন" নয়। @ হান্সের উত্তর দেখুন।
মাইক অ্যাটলাস

@ মাইক ফার্স্ট আমি বলেছিলাম যে তিনি যেভাবে এটি করছেন তা সঠিক এবং তিনি মূল চেষ্টা করতে পারেন / ধরতে পারেন। আমি নিশ্চিত নই যে যখন আমি হান্সের সাথে একমত হয়েছি তখন কেন আপনি (বা অন্য কেউ) আমাকে ভোট দিয়েছেন, যা আমি চেক পাওয়ার আশা করছিলাম না providing এটি সত্যিই ন্যায্য নয়, এবং তারপরে অ্যাপডোমাইন আনহানডেলড এক্সসেপশন প্রক্রিয়া যে মাইনে চেষ্টা করে / ধরতে পারে না তার ব্যতিক্রম কীভাবে ধরা যায় তার কোনও প্রমাণ না দিয়ে বিকল্পটি ভুল বলে। আমি কেন এটি ভুল তা প্রমাণ না করেই কিছু ভুল বলে ভুল বলে মনে করি, কেবল এটি বলা হয়, এটি করে না।
রডনি এস ফোলে

5
আপনি যে উদাহরণটি জিজ্ঞাসা করছেন তা আমি পোস্ট করেছি। দয়া করে দায়ী থাকুন এবং মাইকের পুরানো উত্তরগুলি থেকে আপনার অপ্রাসঙ্গিক ডাউন ভোটগুলি সরিয়ে ফেলুন remove (কোনও ব্যক্তিগত আগ্রহ নেই, কেবল সিস্টেমের এ জাতীয় অপব্যবহারগুলি দেখতে পছন্দ করবেন না))
ব্লুমোনকএমএন

3
তবুও আপনি এখনও সে একই "গেম" খেলেন, কেবল খারাপ দিক থেকে কারণ এটি খাঁটি প্রতিশোধ নেওয়া, কোনও উত্তরের মানের উপর ভিত্তি করে নয়। সমস্যা সমাধানের জন্য এটি কোনও উপায় নয়, কেবল এটি আরও খারাপ করুন। আপনার উত্তর সম্পর্কে বৈধ উদ্বেগ ছিল এমন কারও বিরুদ্ধে প্রতিশোধ নেওয়ার সময় এটি বিশেষত খারাপ (যেমনটি আমি দেখিয়েছি)।
BlueMonkMN

3
ওহ, আমি আরও যোগ করব যে ডাউন-ভোটিং "সম্পূর্ণ বোকা বা নিয়ম লঙ্ঘনকারী" লোকদের জন্য নয়, বরং উত্তরের মানের বিচার করা। আমার কাছে মনে হয় যে ডাউন-ভোটিং উত্তরগুলি যে ব্যক্তিকে প্রদান করেছে সে সম্পর্কে "মন্তব্য" করার জন্য, ভোটটি সঠিক কিনা তা নির্বিশেষে নিজেই উত্তরের সামগ্রীর উপর ভিত্তি করে ডাউন-ভোটিং উত্তরগুলির চেয়ে অনেক বড় আপত্তি। এটিকে ব্যক্তিগতভাবে / গ্রহণ করবেন না।
BlueMonkMN
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.