সিনক্রোনাস C# কোডে, এক্সেপশন কল স্ট্যাকে উপরে প্রপাগেট হয় যতক্ষণ না উপযুক্ত catch ব্লক পায়। কিন্তু অ্যাসিনক্রোনাস মেথডে এক্সেপশন হ্যান্ডলিং उतना সিম্পল নয়।
C#-এ অ্যাসিনক্রোনাস মেথডের তিনটি রিটার্ন টাইপ হতে পারে: void, Task, এবং Task<T>। যখন Task বা Task<T> রিটার্ন টাইপ वाले অ্যাসিনক্রোনাস মেথডে এক্সেপশন হয়, তবে এক্সেপশন অবজেক্ট AggregateException-এ র্যাপ হয়ে Task অবজেক্টের সাথে আট্যাক হয়। একাধিক এক্সেপশন হলে সেগুলো Task-এ স্টোর হয়।
কিন্তু async void মেথডে এক্সেপশন হলে সেটি কল স্ট্যাকে প্রপাগেট হয় না, বরং সরাসরি SynchronizationContext-এ গিয়ে ক্র্যাশ করতে পারে। তাই async void এড়িয়ে async Task ব্যবহার করা উচিত।
উদাহরণ: async Task থেকে এক্সেপশন ক্যাচ
static async Task Main(string[] args)
{
await DoSomething();
Console.ReadLine();
}
public static async Task Foo()
{
throw new ArgumentNullException();
}
public static async Task DoSomething()
{
try
{
await Foo();
}
catch (ArgumentNullException ex)
{
Console.WriteLine(ex);
}
}
আউটপুট
System.ArgumentNullException: Value cannot be null.
at DemoApplication.Program.Foo() in C:\...\Program.cs:line 37
at DemoApplication.Program.DoSomething() in C:\...\Program.cs:line 44
async void এক্সেপশন হ্যান্ডলিং (নন-প্রস্তাবিত):
public async void BadMethod()
{
throw new InvalidOperationException("Oops!");
}
// এটি কল করতে হবে এমনভাবে:
try { BadMethod(); }
catch { /* এটি ক্যাচ হবে না! */ }
সমাধান: সবসময় async Task বা async Task<T> রিটার্ন করুন। শুধু ইভেন্ট হ্যান্ডলারের জন্য async void গ্রহণযোগ্য।