PDA

View Full Version : مدیریت استثناء در نخ جدید



SajjadKhati
شنبه 22 بهمن 1401, 15:28 عصر
سلام
دوستان ، در async await (و کلا در زمانی که درون نخ جدیدی هستیم) ، مدیریت استثناء ها چجوری هه؟

مقاله زیر را یه نگاه بسیار گذرا کردم و فرضا کدی شبیه اونچه نوشته بود نوشتم اما خطا ، مدیریت نمیشه :

Exception handling (Task Parallel Library) | Microsoft Learn (https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/exception-handling-task-parallel-library)

C#‎‎‎ - What is the best way to catch exception in Task? - Stack Overflow (https://stackoverflow.com/questions/12980712/what-is-the-best-way-to-catch-exception-in-task)



void ExceptionHandler(Task task)
{
MessageBox.Show(task.Exception.Message);
}




private async void MethodAsync()
{
Task fibonacciTask = Task.Factory.StartNew(() => { throw new Exception("Test"); });
//await fibonacciTask.ContinueWith(new Action<Task>(this.ExceptionHandler),
// TaskContinuationOptions.OnlyOnFaulted);


try
{
await fibonacciTask;
}
catch (AggregateException e)
{
MessageBox.Show(e.Message);
}
}





void ExceptionHandler(Task task)
{
MessageBox.Show(task.Exception.Message);
}




private async void MethodAsync()
{
Task fibonacciTask = new Task(() => { throw new Exception("Test"); });
fibonacciTask.ContinueWith(new Action<Task>(this.ExceptionHandler),
TaskContinuationOptions.OnlyOnFaulted);


try
{
fibonacciTask.Start();
await fibonacciTask;
}
catch (AggregateException e)
{


}
}



در کد دوم هم که میگه با پارامتر TaskContinuationOptions.OnlyOnRanToCompletion ئه متد ContinueWith میتونیم مدیریت کنیم ، باز هم فرقی نکرد .
در کد بالا ، بجای await fibonacciTask ، از متد Await هم طبق کد لینک اول گذاشتم ، باز هم فرقی نکرد .

من با .NetFramework 4.6.2 کار میکنم .
الان اونچه در اون لینک ها گفتن ، کار میکنه؟ یا برای من یا برای نسخه ی دات نت فریم وورک هست؟

تشکر

Mahmoud.Afrad
دوشنبه 24 بهمن 1401, 08:32 صبح
هر exception ای لزوما AggregateException نیست.
در کد شما اصلاح کنید به
catch (Exception e)

SajjadKhati
دوشنبه 24 بهمن 1401, 11:18 صبح
هر exception ای لزوما AggregateException نیست.
در کد شما اصلاح کنید به
catch (Exception e)

سلام
بله حواسم نبود .

اما فرقی نداره . کلا مدیریت نمیشه .
تشکر

SajjadKhati
سه شنبه 25 بهمن 1401, 22:54 عصر
سلامی مجدد
خیلی ممنون
اگه از اون متدی که async await توش بکار میره ، از نوع Task باشن ، حتی بدون try catch هم فقط زمانی که بدون استفاده از visual studio (یا فقط با استفاده از گزینه ی start without debugging) ، پروژه را اجرا میکنیم ، حتی در این صورتی که exception را پرتاب کردیم هم هیچ خطایی نمیده .
اما اگه خروجی اون متدها را از نوع void بگیریم ، exception پرتاب میشه .

اما منظورم هیچ کدوم شون زمان اجرای برنامه توسط visual studio نبودن (یا فقط با استفاده از گزینه ی start without debugging) .



private async Task MethodAsync()
{
Task fibonacciTask = Task.Factory.StartNew(() => { throw new Exception("Test"); });
await fibonacciTask;
}



============


همچنین اینکه همونطور که گفته بودن در همون لینک ، همه ی اونها ، برای زمانی که برنامه را با اون حالت اجرا میکنیم (یا بدون دیباگ) ، درست هست .

یعنی در اون حالت اجرا (زمان اجرا بدون استفاده از ویژال استودیو یا با حالت بدون دیباگ اش) ، وقتی قسمتِ await را در try catch بذاریم ، exception هایی که در نخ جدید (که همون در Task های اجرا شده هست) پرتاب میکنیم ، هندل و مدیریت میشن .
البته نکته هم که باید یادمون باشه اینه که خروجی این متدهایی که کلمه ی کلیدی async await توشون بکار میبریم هم را تا جای ممکن (معمولا بجز رویدادها) ، از نوع Task یا کلا نوع جنریکش بگیریم .




private async Task MethodAsync()
{
Task fibonacciTask = Task.Factory.StartNew(() => { throw new Exception("Test"); });
try
{
await fibonacciTask;
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}


تشکر

Mahmoud.Afrad
چهارشنبه 26 بهمن 1401, 00:32 صبح
مشکلی ندارد
لینک
https://dotnetfiddle.net/Bc6XVN