در چشم انداز همیشه در حال تحول توسعه نرم افزار، پاسخگویی و کارایی برنامه در درجه اول اهمیت قرار دارند. کاربران انتظار دارند برنامه ها سریع، روان و پاسخگو باشند، حتی زمانی که با عملیات طولانی مدت یا فشرده سروکار دارند. در قلمرو توسعه C#‎.NET، برنامه نویسی غیر همزمان به عنوان یک تکنیک قدرتمند برای دستیابی به این اهداف ظاهر شده است.
کینگتو - آموزش برنامه نویسی تخصصصی - دات نت - سی شارپ - بانک اطلاعاتی و امنیت

برنامه نویسی غیر همزمان در C#‎.NET: راهنمای جامع

28 بازدید 0 نظر ۱۴۰۴/۰۲/۱۳

این مقاله به بررسی مفهوم برنامه نویسی غیر همزمان در C#‎.NET می پردازد، مزایای آن را بررسی می کند، مکانیسم های زیربنایی را تشریح می کند و بهترین شیوه ها را برای استفاده موثر ارائه می دهد.

برای درک اهمیت برنامه نویسی غیر همزمان، ضروری است که بین اجرای همزمان و غیر همزمان تمایز قائل شویم.

  • برنامه نویسی همزمان: در برنامه نویسی همزمان، عملیات به صورت متوالی اجرا می شوند، به این معنی که هر عملیات قبل از شروع عملیات بعدی باید کامل شود. این رویکرد ساده است اما می تواند منجر به مسدود شدن رابط کاربری یا کاهش پاسخگویی برنامه در هنگام انجام عملیات طولانی مدت شود.
  • برنامه نویسی غیر همزمان: از طرف دیگر، برنامه نویسی غیر همزمان به برنامه اجازه می دهد تا عملیاتی را آغاز کند و بدون منتظر ماندن برای تکمیل آنها به اجرای سایر وظایف ادامه دهد. این رویکرد پاسخگویی برنامه را افزایش می دهد، تجربه کاربری را بهبود می بخشد و امکان استفاده کارآمدتر از منابع سیستم را فراهم می کند.

مزایای برنامه نویسی غیر همزمان

برنامه نویسی غیر همزمان در C#‎.NET مزایای بی شماری را ارائه می دهد، از جمله:

  • افزایش پاسخگویی: برنامه نویسی غیر همزمان از مسدود شدن رشته اصلی برنامه (رشته UI در برنامه های دسکتاپ یا موبایل) جلوگیری می کند و به برنامه اجازه می دهد به تعاملات کاربر پاسخگو بماند و تجربه کاربری روانی را ارائه دهد.
  • بهبود عملکرد: با واگذاری عملیات طولانی مدت به رشته های پس زمینه، برنامه نویسی غیر همزمان امکان استفاده کارآمدتر از منابع سیستم، مانند CPU و حافظه را فراهم می کند. این می تواند منجر به بهبود عملکرد و توان عملیاتی برنامه شود.
  • مقیاس پذیری بهتر: در برنامه های کاربردی سمت سرور، برنامه نویسی غیر همزمان می تواند توانایی برنامه را برای رسیدگی به چندین درخواست همزمان افزایش دهد. با آزاد کردن رشته ها برای رسیدگی به درخواست های جدید در حالی که عملیات طولانی مدت در پس زمینه در حال انجام هستند، برنامه می تواند تعداد بیشتری از کاربران را به طور همزمان مدیریت کند.
  • تجربه کاربری غنی تر: برنامه نویسی غیر همزمان به توسعه دهندگان این امکان را می دهد تا رابط های کاربری غنی تری را با انیمیشن ها، نشانگرهای پیشرفت و بازخورد بلادرنگ ایجاد کنند، بدون اینکه پاسخگویی برنامه را به خطر بیندازند.

 

Async و Await: هسته برنامه نویسی غیر همزمان

C#‎.NET مدل برنامه نویسی غیر همزمان مبتنی بر وظیفه (TAP) را از طریق کلمات کلیدی async و await ارائه می دهد. این کلمات کلیدی انتزاعی را بر روی مکانیسم های پیچیده مدیریت رشته ارائه می دهند و نوشتن کد غیر همزمان را آسان تر و خواناتر می کنند.

  • Async: کلمه کلیدی async برای تعیین یک روش به عنوان غیر همزمان استفاده می شود. یک متد async می تواند حاوی یک یا چند عبارت await باشد.
  • Await: کلمه کلیدی await برای مکث اجرای یک متد async تا زمانی که یک عملیات غیر همزمان کامل شود، بدون مسدود کردن رشته فعلی، استفاده می شود. هنگامی که عملیات غیر همزمان کامل می شود، اجرا در ادامه متد async از سر گرفته می شود.

مکانیسم های زیربنایی

در زیر کاپوت، کلمات کلیدی async و await با همکاری چارچوب Task Parallel Library (TPL) برای مدیریت عملیات غیر همزمان کار می کنند. هنگامی که یک متد async با یک عبارت await مواجه می شود، کامپایلر یک ماشین حالت ایجاد می کند که اجرای متد را به حالت تعلیق در می آورد و عملیات غیر همزمان را آغاز می کند.

عملیات غیر همزمان معمولاً روی یک رشته از استخر رشته یا از طریق مکانیزم تکمیل I/O اجرا می شود. هنگامی که عملیات کامل شد، ماشین حالت از سر گرفته می شود و اجرای متد async ادامه می یابد. این فرآیند تضمین می کند که رشته اصلی برنامه آزاد می ماند تا به سایر وظایف رسیدگی کند.

 

بهترین شیوه ها برای برنامه نویسی غیر همزمان

برای استفاده موثر از برنامه نویسی غیر همزمان در C#‎.NET، رعایت بهترین شیوه های زیر ضروری است:

از Async Void اجتناب کنید: متدهای async void برای کنترل کننده های رویداد طراحی شده اند، اما فاقد مکانیزم مناسب برای رسیدگی به خطا هستند. برای همه متدهای غیر همزمان دیگر، از async Task یا async Task به جای آن استفاده کنید.

  • نامگذاری قراردادها: متدهای غیر همزمان را با پسوند "Async" نامگذاری کنید تا به وضوح ماهیت غیر همزمان آنها را نشان دهید (به عنوان مثال، GetDataAsync، ProcessFileAsync).
  • مدیریت خطا: از بلوک های try-catch برای رسیدگی به استثنائات در متدهای غیر همزمان درست مانند متدهای همزمان استفاده کنید. استثنائات پرتاب شده در طول یک عملیات غیر همزمان به متد async تماس گیرنده منتقل می شوند.
  • پیکربندی انتظار: از ConfigureAwait(false) برای جلوگیری از بازگشت به زمینه همگام سازی اصلی پس از یک انتظار استفاده کنید، مگر اینکه به طور خاص به آن نیاز داشته باشید. این می تواند عملکرد را در برنامه های کاربردی غیر UI بهبود بخشد.
  • از مسدود کردن کد غیر همزمان خودداری کنید: فراخوانی متدهای .Wait() یا .Result در یک متد async منتظر می ماند تا عملیات غیر همزمان کامل شود و به طور موثر آن را به یک تماس همزمان تبدیل می کند. این می تواند منجر به بن بست یا کاهش پاسخگویی شود. همیشه از await برای صبر کردن برای تکمیل عملیات غیر همزمان استفاده کنید.
  • از IAsyncEnumerable برای جریان داده استفاده کنید: هنگامی که با مجموعه بزرگی از داده ها سروکار دارید که می توانند به صورت تدریجی پردازش شوند، از IAsyncEnumerable و await foreach برای مصرف غیر همزمان داده ها با در دسترس قرار گرفتن آنها استفاده کنید. این می تواند مصرف حافظه را کاهش دهد و پاسخگویی را بهبود بخشد.

 

سناریوهای دنیای واقعی

برنامه نویسی غیر همزمان در C#‎.NET در طیف گسترده ای از سناریوهای دنیای واقعی کاربرد دارد، از جمله:

  • برنامه های کاربردی دسکتاپ و موبایل: برای حفظ پاسخگویی رابط کاربری در هنگام انجام عملیاتی مانند دسترسی به داده ها، دانلود فایل ها یا انجام محاسبات پیچیده.
  • برنامه های کاربردی وب: برای رسیدگی به درخواست های همزمان متعدد، دسترسی به پایگاه داده و برقراری ارتباط با سرویس های خارجی بدون مسدود کردن رشته های سرور.
  • برنامه های کاربردی مبتنی بر ابر: برای ایجاد خدمات مقیاس پذیر و پاسخگو که می توانند حجم زیادی از درخواست ها را مدیریت کنند.
  • برنامه های کاربردی بی درنگ: برای پردازش داده ها و رویدادها در زمان واقعی، مانند برنامه های چت، فیدهای خبری و سیستم عامل های بازی.

 

مثال های کاربردی از برنامه نویسی غیر همزمان در C#‎.NET
در اینجا چند مثال عملی از برنامه نویسی غیر همزمان در C#‎.NET برای نشان دادن کاربرد آن در سناریوهای مختلف آورده شده است:

1. دانلود داده از یک API وب

public async Task DownloadDataAsync(string url)
{
    using (HttpClient client = new HttpClient())
    {
        // ارسال یک درخواست GET غیر همزمان به URL مشخص شده
        HttpResponseMessage response = await client.GetAsync(url);
        response.EnsureSuccessStatusCode(); // پرتاب خطا برای کدهای وضعیت ناموفق

        // خواندن محتوای پاسخ به عنوان یک رشته به صورت غیر همزمان
        string result = await response.Content.ReadAsStringAsync();
        return result;
    }
}

// فراخوانی متد غیر همزمان
string data = await DownloadDataAsync("https://api.example.com/data");
Console.WriteLine(data);

در این مثال، متد DownloadDataAsync داده ها را از یک API وب به صورت غیر همزمان دانلود می کند. HttpClient.GetAsync و HttpContent.ReadAsStringAsync هر دو متدهای غیر همزمان هستند که با کلمه کلیدی await منتظر می مانند. این به برنامه اجازه می دهد تا در حین دانلود داده ها به عملیات دیگر ادامه دهد.

2. خواندن یک فایل بزرگ

public async Task ReadFileAsync(string filePath)
{
    using (StreamReader reader = new StreamReader(filePath))
    {
        // خواندن محتوای فایل به صورت غیر همزمان
        string content = await reader.ReadToEndAsync();
        return content;
    }

// فراخوانی متد غیر همزمان
string fileContent = await ReadFileAsync("largefile.txt");
Console.WriteLine(fileContent);}

این مثال محتوای یک فایل بزرگ را به صورت غیر همزمان با استفاده از StreamReader.ReadToEndAsync می خواند. این از مسدود شدن رشته اصلی برنامه در هنگام خواندن فایل جلوگیری می کند و پاسخگویی برنامه را حفظ می کند.

3. انجام محاسبات فشرده CPU

public async Task CalculateSumAsync(int n)
{
    // انجام محاسبات فشرده CPU در یک رشته پس زمینه
    int result = await Task.Run(() =>
    {
        int sum = 0;
        for (int i = 1; i <= n; i++)
        {
            sum += i;
        }
        return sum;
    });
    return result;
}

// فراخوانی متد غیر همزمان
int sum = await CalculateSumAsync(1000000);
Console.WriteLine($"Sum: {sum}");

در این مثال، متد CalculateSumAsync مجموع اعداد از 1 تا n را با استفاده از Task.Run در یک رشته پس زمینه محاسبه می کند. این از مسدود شدن رشته اصلی برنامه در هنگام انجام محاسبات جلوگیری می کند.

4. به روز رسانی رابط کاربری

public async Task UpdateUIAsync()
{
    // به روز رسانی یک عنصر رابط کاربری به صورت غیر همزمان
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        MyProgressBar.Value = 50; // به روز رسانی نوار پیشرفت
        MyTextBlock.Text = "Processing..."; // به روز رسانی متن
    });

    // انجام عملیات طولانی مدت
    await Task.Delay(2000); // شبیه سازی یک عملیات طولانی مدت

    // به روز رسانی مجدد رابط کاربری
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        MyProgressBar.Value = 100; // به روز رسانی نوار پیشرفت
        MyTextBlock.Text = "Completed!"; // به روز رسانی متن
    });
}

// فراخوانی متد غیر همزمان
await UpdateUIAsync();

این مثال نحوه به روز رسانی عناصر رابط کاربری را به صورت غیر همزمان در یک برنامه UWP نشان می دهد. Dispatcher.RunAsync برای اجرای کد در رشته UI استفاده می شود. این تضمین می کند که به روز رسانی های رابط کاربری به صورت روان انجام می شوند و برنامه پاسخگو می ماند.

اینها تنها چند نمونه از چگونگی استفاده از برنامه نویسی غیر همزمان در C#‎.NET هستند. با استفاده از async و await، می توانید برنامه های پاسخگوتر، کارآمدتر و مقیاس پذیرتری ایجاد کنید.

نتیجه گیری

برنامه نویسی غیر همزمان یک تکنیک قدرتمند است که به توسعه دهندگان C#‎.NET امکان می دهد برنامه های پاسخگوتر، کارآمدتر و مقیاس پذیرتر ایجاد کنند. با درک اصول، استفاده موثر از کلمات کلیدی async و await و پیروی از بهترین شیوه ها، توسعه دهندگان می توانند از مزایای کامل برنامه نویسی غیر همزمان استفاده کرده و تجربه کاربری استثنایی را ارائه دهند.

لینک استاندارد شده: 71ly

0 نظر

    هنوز نظری برای این مقاله ثبت نشده است.