مروری بر Async Await در #C
چهارشنبه 5 آبان 1395در برنامه های واقعی ، برای مثال شما میخواهید هنگامی که از یک سایت چیزی را دانلود میکنید ، همزمان نیز از آن استفاده بکنید . در این مقاله ، هدف ما چگونگی انجام این کار با معرفی async است .
آماده سازی فضای برنامه نویسی :
در این مقاله ما از Visual Studio 2015 استفاده خواهیم کرد . برای شروع کار، ابتدا Visual Studio را باز کنید :
در مرحله بعد ، یک Console Application با نام AsyncSample ایجاد کنید :
بعد ایجاد پروژه فضای برنامه نویسی ما همانند تصویر زیر خواهد بود :
قبل از شروع به کدنویسی و ایجاد برنامه با یکسری از کلمات کلیدی بیشتر آشنا خواهیم شد :
Async : ما برای اینکه مشخص کنیم که یک متد Asynchronous است از معرف asynv استفاده میکنیم . توافقات بر این منوال است که اینگونه متد ها را async method بنامیم .
Await : عملگر await به یک task در یک متد async اطلاق میشود ، که باعث میشود تا زمان اتمام یافتن آن task ، اجرای متد به حالت تعلیق دربیاید . عملگر await فقط در متدهایی قابل استفاده میباشند که دارای async modifier باشند .
نکته : توجه داشته باشید که ما تعاریف کلمات کلیدی فوق را بصورت ساده و روان بیان کردیم . شما میتوانید برای کسب اطلاعات بیشتر و دیدن تعریفات رسمی تر به سایت msdn.microsoft.com مراجعه فرمایید .
اولین متد Asynchronous :
در این قسمت ، به سراغ کد نویسی میرویم . کد زیر را در visual studio جایگذاری کنید :
using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AsyncSample { class Program { static void Main(string[] args) { Loop(); Console.WriteLine("End of Work ..."); Console.ReadKey(); } public static async void Loop() { for (int i = 1; i <= 10; i++) { Console.WriteLine(i); } } } }
خروجی برنامه بصورت زیر میباشد :
خروجی این برنامه بسیار ساده میباشد ، ما اعداد 1 تا 10 را در خروجی مشاهده خواهیم کرد و در آخر هم جمله End of Work ظاهر خواهد شد .
زمانی که برنامه برای اتمام این فراخوانی منتظر مانده بود ، برنامه Main مسدود شده بود و تا زمانی که کار حلقه for به اتمام برسد . اگر برنامه شما ، یک برنامه تحت desktop بود در همچین وضعیتی برنامه شما به حالت freez میرفت و در این حالت کاربر تصور میکرد که برنامه هنگ کرده و به مشکلی برخورده است در حالی که حقیقت چیز دیگریست و برنامه منتظر است تا حلقه به اتمام برسد .
مراحل برنامه نویسی Asynchronous با Async Await :
حال به سراغ نوشتن کدی در مُد Async میرویم . اولین چیزی که مورد نیاز است ، راهی برای وارد کرد پشته Asynchronous است . در برنامه desktop همچین کاری به عنوان یک event handler میباشد که در ازای کلیک یک دکمه اجرا میشود . اگرچه ، برای این برنامه ، ما کد زیر را در نظر میگیریم :
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AsyncSample { class Program { static void Main(string[] args) { ThisWouldNormallyBeAnEventHandler(); Console.WriteLine("End of line..."); Console.ReadKey(); } public static async void ThisWouldNormallyBeAnEventHandler() { for (int i = 0; i < 10; i++) { Console.WriteLine(i); await Task.Delay(1); } } } }
به عنوان یک قانون ، async void برای event handlerها یا متد های سطح بالا هستند که اجازه پردازش به Asynchronous method میدهند . در Console Application این اجازه به متد main داده نمیشود که async باشد برای همین ما از async void method برای وارد کردن asynchronous stack استفاده میکنیم .
حال برنامه را برای مشاهده خروجی آن اجرا کنید :
اتفاقی که در کد میافتد بدین صورت است که بعد از ایجاد تاخیر در حلقه ، برنامه متوقف نمیشود بلکه به سراغ ادامه کد در main میرود و آن را به صورت async اجرا میکند . حال
await Task.Delay(1);
و نتیجه را مشاهده کنید . زمانی که خطی را حذف میکنید دارای کلمه کلیدی await است و متد آن هنوز دارای کلمه کلیدی async است ، این متد همچنان syncronous کار میکند . که احتمالا InteliSnce زیر نام متد خط کشیده و به شما هشداری را خواهد داد که منظور آن این است که در اینجا یک متد async وجود دارد که دارای کلمه کلیدی await نیست .
در ادامه در مورد ()Task.Delay صحبت خواهیم کرد .
نوع بازگشتی 'Task 'the Awaitable :
حال ، به متد async با نوع بازگشتی void نگاهی بیندازید . حال هدف این بخش این است ، که نوع داده ای غیر از void را بازگردانیم ، برای این کار شما میتوانید همانند زیر عمل کنید :
public static void Main() { ThisWouldNormallyBeAnEventHandler(); Console.WriteLine("End of line..."); Console.ReadKey(); } public static async void ThisWouldNormallyBeAnEventHandler() { await LoopAsync(); } public static async Task LoopAsync() { for (int i = 0; i < 10; i++) { Console.WriteLine(i); await Task.Delay(1); } }
برعکس async void که awaitable نبود ، متد ()LoopAsync یک متدی است که میتوان از کلمه کلیدی await برای آن استفاده کرد ، همین امر ()ThisWouldNormallyBeAnEventHandler را قادر به suspend کردن اجرای برنامه تا زمان کامل شدن متد ()LoopAsync میکند . در راستای همین امر ، همانند مثال قبلی که ارائه شد ، ادامه متد Main ما اجرا میشود .
به این نکته توجه داشته باشید که نام متد ما Loop است و بنا به قرارداد نام گذاری برای متدهای asyn به انتهای نام متد خود یک Async اضافه میکنیم . که نشان میدهد که این متد واقعا Async میباشد .
بخاطره مقاله ما ، متد ما asynchronous است و دلیل آن await در ()Task.Delay میباشد . در برنامه های واقعی ، این میتواند یک source را از اینترنت دانلود کند و شما میخواهید در زمان دانلود نیز با برنامه کار کنید .
پیرو قولی که در مورد توضیح ()Task.Delay داده بودیم ، در این مرحله به توضیح آن میپردازیم .
یک راه ثانویه عالی برای استفاده از ()Thread.Sleep میباشد . آن non-blocking است و در مدت durationای که شما آن را مشخص میکنید ، thread که باید اجرا شود ، فراخوانی میشود . زمانی که duration ای که آن به اتمام رسید ، به نقطه ای بازمیگردد که در آنجا فراخوانی شده بود . دقیقا برعکس Thread.Sleep ، که تمام اجراهای Thread ای که در آن است را Suspend میکند .
یک نگاه سریع و اجمالی هم به <Task<T میندازیم . اگر شما قصد دارید که متد شما مقداری با نوع Boolean باز گرداند..همانند زیر عمل کنید :
async Task<bool> LoopAsync()
زمانی که یک استاندارد مقدار true را بازمیگرداند . کار میکند . اگرچه ، این فقط زمانی کار میکند که متد با کلمه کلیدی modify ، async شده باشد . Taskهای دیگری نیز وجود دارد که این مقاله پتانسیل کافی برای ارائه شدن آنها را ندارد و در مقاله های بعدی آن هارا ارائه خواهیم داد . Async Task در کد ، در مقابل Async voidها ، مثل آب خوردن میباشند . Async Void ها با استفاده از event handler ها به شما اجازه دسترسی به stack را میدهند ، در ضمن ، Async voidها منطق کنترل خطای متفاوتی با Async Task ها دارند .
آموزش سی شارپ
- C#.net
- 2k بازدید
- 3 تشکر