لطفا در مورد متد ConfigureAwait و کاربرد اون در سی شارپ راهنمایی کنید
متشکرم
سلام. تا جایی که من می دونم از این متد زمانی استفاده میکنند که میخوان یک رویداد رو به صورت مستقل اجرا کنند طوری که UI سیستم درگیر این متد نشه و باعث قفل شدن برنامه نشه. به طور مثال شما میخواهید وقتی کاربر یک نرم افزار را اجرا میکنه، بعد از مدت 1 دقیقه پیغامی به کاربر بده و اون رو از موضوعی با خبر کنه و یا اینکه بدون اینکه از تایمر استفاده کنید بعد از مدت زمان خاصی یک تابع رو اجرا کنید. به مثال زیر دقت کنید. فرض کنید تابع زیر رو در هنگام لود نرم افزار قرار میدیم.
private void UserAlarm()
{
Task.Delay(60000);
MessageBox.Show("لطفا نرم افزار را به روزرسانی کنید");
}
این متد در هنگام اجرا بعد از مدت یک دقیقه پیغامی به صورت مسیج باکس به کاربر میده ولی یه مشکلی داره که تا این مدت یک دقیقه نرم افزار قفل میشه و کاربر هیچ کاری نمیتونه انجام بده. ولی اگر همین تابع رو به صورت زیر بنویسیم دیگه نرم افزار قفل نمیشه.
private async void ProcessAsync()
{
await Task.Delay(60000);
MessageBox.Show("لطفا نرم افزار را به روزرسانی کنید");
}
این تابع به صورت همزمان و مستقل عمل میکنه طوری که UI سیستم رو درگیر نمیکنه و باعث قفل شدن نرم افزار نمیشه.
البته این یک مورد استفاده از ConfigureAwait هست و موارد استفاده دیگه ای هم داره.
کاربرد متد ConfigureAwait
این مورد توضیحش کمی پیچیدس و نیاز داره یه سری موارد رو قبلش بدونین مثل SynchronizationContext و TaskScheduler ولی خیلی ساده بخوام توضیح بدم اینکه وقتی متد async ایی رو فراخوانی میکنید اون تکه کد داخل متد async ایی توسط یک Thread دیگه [ترد ثانویه] (متفاوت از ترد [اصلی] - ترد فراخوانی کننده متد) اجرا میشه (البته نه الزاما ولی در متد های async IO bound بله)
حالا اگه داخل اون متد async ایی نیاز به دسترسی به اشیایی از Context ترد اصلی نیاز داشته باشید، باید [ترد ثانویه] برگرده به Context ترد اصلی [اصلی] تا بتونه به اشیا اون دسترسی داشته باشه وگرنه خطا میده که "یک ترد نمیتونه به اشیا ترد دیگه دسترسی داشته باشه"
مثلا توی WinForm بخواید مقدار یک کنترل UI مثل TextBox رو بخونید/عوض کنید یا مثلا توی ASPNET MVC (به جز ASP Core چون قضیه اش فرق داره) مثلا بخواهد یه چیزی رو از HttpContext.Current بخونید/تغییر بدید. چون این اشیایی که گفتم مال ترد اصلی هست، ترد ثانویه نمیتونه به اون دسترسی پیدا کنه.
به طور پیشفرض وقتی ما یک متد async رو به صورت عادی await میکنیم، پس از اتمام Task مربوطه، ترد ثانویه برمیگرده به Context ترد اصلی و ما بدون هیچ مشکلی میتونیم به اشیا Context ترد اصلی دسترسی پیدا کنیم ولی این قضیه یه سرباری رو داره تحمیل میکنه که بعضی وقتا بهش نیازی نیست
مثلا وقتی که ما یک کد general-purpose (غیر وابسته به Context خاصی) رو مینویسیم (مثلا کدی که به UI Control ها توی WinForm یا HttpContext.Current توی ASPNET MVC نیازی نداره) مثل یک کد دانلود یک فایل از اینترنت یا انجام عملیات با دیتابیس؛ توی این موارد میتونیم با غیر فعال کردن "بحث Sync شدن Context ها" از این سربار اضافی راحت بشیم
در مقابل وقتی ما داریم یک کد application-level (وابسته به Context خاص) رو مینویسیم (مثلا کدی که به UI Control ها توی WinForm یا HttpContext.Current توی ASPNET MVC نیاز داره) باید این قابلیت رو داشته باشیم حتما وگرنه به مشکل میخوریم (خطای "یک ترد نمیتونه به اشیا ترد دیگه دسترسی داشته باشه")
واسه غیر فعال کردن این امکان باید بر روی متد های async مون از متد ConfigureAwait با مقدار (false) استفاده کنیم . مثال
await httpClient.GetAsync(url).ConfigureAwait(false)
این مورد از dead-lock هم جلوگیری کنه در مواقتی که متد async ایی رو به صورت sync فراخوانی میکنید. مثلا :
asyncMethod.Wait();
یا
asyncMethod.Result;
یا
asyncMethod.GetAwaiter().GetResult();
نتیجه :
🔸وقتی که کد general-purpose مینویسید بهتره از متد ConfigureAwait با مقدار (false) استفاده کنید.
🔹ولی وقتی که کد application-level مینویسید به هیچ وجه این کارو نکنید.
🔰نکته :
1 - توی ASPNET Core چون به صورت پیشفرض SynchronizationContext خاص خودش رو نداره فرقی هم نمیکنه از ConfigureAwait استفاده بکنین یا نه (البته تا مادامی که به صورت دستی SynchronizationContext ایی ست نکرده باشین)
2 - متد هایی که توسط Task.Run هم اجرا میشن نیازی به ConfigureAwait ندارن چون Task.Run به صورت ضمنی TaskScheduler.Default استفاده میکنه پس SynchronizationContext ترد اجرا کننده null میشه. (اینم تا مادامی که به صورت دستی SynchronizationContext ایی ست نکرده باشین)
برای اطلاعات بیشتر در این مورد کلیک کنید.
تاریخ :
1403/05/30
- ساعت :
09:22:00 AM
- بازدید :
473
- پاسخ :
1
|
تاریخ :
1402/08/16
- ساعت :
10:38:00 AM
- بازدید :
1378
- پاسخ :
1
|
تاریخ :
1402/09/08
- ساعت :
07:34:00 PM
- بازدید :
1172
- پاسخ :
1
|
تاریخ :
1402/09/21
- ساعت :
11:10:00 PM
- بازدید :
616
- پاسخ :
1
|
تاریخ :
1403/07/13
- ساعت :
12:06:00 PM
- بازدید :
373
- پاسخ :
1
|
تاریخ :
1403/06/24
- ساعت :
08:52:00 PM
- بازدید :
335
- پاسخ :
1
|
تاریخ :
1398/09/14
- ساعت :
01:58:00 PM
- بازدید :
4294
- پاسخ :
1
|
تاریخ :
1398/09/16
- ساعت :
11:41:00 AM
- بازدید :
4299
- پاسخ :
1
|
تاریخ :
1398/09/07
- ساعت :
02:15:00 PM
- بازدید :
3898
- پاسخ :
5
|
تاریخ :
1403/05/16
- ساعت :
05:43:00 AM
- بازدید :
686
- پاسخ :
0
|
تاریخ :
1403/09/06
- ساعت :
09:51:00 PM
- بازدید :
87
- پاسخ :
1
|
تاریخ :
1400/07/17
- ساعت :
10:39:00 PM
- بازدید :
2335
- پاسخ :
0
|
تاریخ :
1403/09/05
- ساعت :
06:32:00 PM
- بازدید :
70
- پاسخ :
1
|
تاریخ :
1401/02/24
- ساعت :
02:17:00 PM
- بازدید :
2037
- پاسخ :
1
|
تاریخ :
1403/08/29
- ساعت :
07:15:00 PM
- بازدید :
117
- پاسخ :
0
|
تاریخ :
1403/08/18
- ساعت :
10:40:00 AM
- بازدید :
149
- پاسخ :
0
|
تاریخ :
1402/07/23
- ساعت :
04:01:00 PM
- بازدید :
1067
- پاسخ :
1
|
تاریخ :
1403/05/30
- ساعت :
09:22:00 AM
- بازدید :
473
- پاسخ :
1
|
تاریخ :
1402/08/01
- ساعت :
06:25:00 PM
- بازدید :
948
- پاسخ :
1
|
تاریخ :
1402/08/16
- ساعت :
10:38:00 AM
- بازدید :
1378
- پاسخ :
1
|