tgoop.com/fullStackDevs/499
Last Update:
#AsynchronousProgramming
#Async #Await
#Tasks
✳️ Async/Await on a Separate Thread
🔸 اجرای عملیات های long-running به صورت غیر همزمان (asynchronous) در سی شارپ با mark کردن آنها با استفاده از کلمه کلیدی های async/await انجام میشود.
🔹 متد هایی که یک Task را به عنوان خروجی باز میگردانند با استفاده از این کلمه کلیدی ها به صورت غیر همزمان اجرا میشوند.
درواقع از await میتوان به همراه یک awaitable argument استفاده کرد که یک عملیات asynchronous است.
دو نوع رایج awaitable argument ها در دات نت ،
Task , Task<T>
میباشد.
🔹 اجرای متدهای long-running به صورت همزمان (synchronous)، باعث بلاک شدن thread جاری تا زمان اتمام آن متد میشود.
🔹همچنین در اپلیکیشن هایی که رابط گرافیکی کاربری دارید اجرای متد های long-running به صورت همزمان، سبب بلاک شدن thread اجرا کننده رابط گرافیکی (UI) میشود و تا زمان اتمام اجرای آن متد رابط کاربری به صورت فریز شده باقی میماند.
اما چنین متدی که خروجی آن یک Task نیست و نمیتوان آنرا با استفاده از async و await به صورت asynchronous اجرا کرد، را چگونه به یک متد asynchronous تبدیل کنیم تا در یک thread جدا اجرا شود.
اینجاست که Task.Run به کمک ما می آید.
🔸 متد Run از کلاس Task باعث اجرا شدن کد های صف شده در یک thread جدا میشود.
معمولا این thread جدید ازthread pool می آید .
▫️ در واقع thread pool مجموعه ای از worker thread هایی است که توسط .net برای اجرای اپلیکیشن، مدیریت میشوند.
▫️ هم چنین یک worker thread یک thread ای است که به درخواست یک client برای انجام کاری فعال میشود.
🔹 مهمترین نکته این که Task.Run به عنوان خروجی یک Task باز میگرداند که این بدین معنی است که می توانید آنرا await کنید.
متد Task.Run دارای overload های متفاوتی است که به عنوان پارامتر یک Action delegate یا یک Func delegate دریافت میکند.
🔸 تاکنون دانستیم که صدا زدن متد Task.Run برای اجرای یک متد long-running باعث اجرا شدن این متد بروی یک thread جدید در thread pool میشود اما پس از اتمام اجرای این متد long-running بقیه و ادامه کد ها بروی کدامین thread اجرا خواهد شد⁉️
🔸 در اکثر مواقع می خواهیم تا ادامه کار بروی thread اصلی ادامه پیدا کند مخصوصا زمانی که اپلیکیشن دارای یک رابط کاربری گرافیکی میباشد و میخواهیم بعد از انجام شدن آن متد long-running عناصری را بروی رابط گرافیکی در thread اصلی آپدیت نماییم. برای آنجام این کار کافیست Task.Run را await نمایید زیرا زمانی که که یک Task را await می کنید اطلاعات context جاری از SynchronizationContext گرفته میشود تا دوباره به thread اصلی اپلیکیشن باز گردد.
🔻زمانی که روی یک متد ای که به صورت Async اجرا میشود ConfigureAwait(false
) قرار میدهید. بازگشت به context اصلی صورت نمیگیرد.
🔹 اما SynchronizationContext چیست و کار آن چه میباشد؟
🔸 هنگامی که با یک اپلیکیشن UI based کار میکنید وابستگی و ارتباط بین thread ها مسئله بسیار مهمی است
زمانی که با چنین اپلیکیشن هایی کار میکنید محدودیتی که وجود دارد این است که عناصر و کنترلر های صفحه توسط UI thread ساخته شده یا تغییر و آپدیت شوند و اگر نیاز باشد که به عنوان مثال 10 تغییر بروی عناصر صفحه صورت گیرد، این عملیات ها در صف قرار میگیرند تا به صورت متوالی توسط UI thread انجام شوند.
این محدودیت برای کمک به UI framework جهت جلوگیری از پیچیدگی های هماهنگی و مدیریت بین thread های مختلف برای آپدیت عناصر و کنترلر های صفحه صورت گرفته است.
و SynchronizationContext ارتباط با UI thread را به صورت منظم مرتب میکند.
در Asp.net Core اما SynchronizationContext برایر null میباشد.
✳️ درا این قسمت یک overview در مورد Task.Run پرداختیم تا در قسمت بعدی به عملیات های I/O و CPU bound پرداخته و با مفاهیم Asynchronous بیشتر آشنا میشویم.
@FullStackDevs
BY Web Devs
Share with your friend now:
tgoop.com/fullStackDevs/499