۳۰ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

نحوه استفاده از IAsyncEnumerable در سی شارپ

نحوه استفاده از IAsyncEnumerable در سی شارپ را بیاموزید تا به راحتی جریان های پیوسته داده ها را به صورت ناهمزمان فیلتر، تجمیع، تبدیل، پروژه و یا پردازش کنید.

نحوه استفاده از IAsyncEnumerable در سی شارپ را بیاموزید تا به راحتی جریان های پیوسته داده ها را به صورت ناهمزمان فیلتر، تجمیع، تبدیل، پروژه و یا پردازش کنید.

IAsyncEnumerable یک ویژگی قدرتمند معرفی شده در C# 8.0 است که اجازه می دهد ما با دنباله ای از داده ها به صورت ناهمزمان کار کنیم. همانطور که از نام آن پیداست، IAsyncEnumerable همتای ناهمزمان IEnumerable است، رابطی که به ما امکان می‌دهد به راحتی در عناصر یک مجموعه تکرار کنیم.

جالب است که رابط IAsyncEnumerable بر اساس یک رویکرد pull-based کار می کند، جایی که مورد بعدی در صورت درخواست مصرف کننده ایجاد یا بازیابی می شود. برخلاف IEnumerable که منتظر می‌ماند تا عنصر بعدی ایجاد شود، IAsyncEnumerable یک مورد انتظار را برمی‌گرداند که می‌تواند بعداً از سر گرفته شود.

در این مقاله، نحوه استفاده از رابط IAsyncEnumerable در سی شارپ را برای کار با جریان‌های ناهمزمان از داده‌ها بررسی خواهیم کرد.

یک پروژه برنامه کاربردی کنسول در ویژوال استودیو ایجاد کنید

ابتدا، اجازه دهید یک پروژه برنامه کاربردی کنسول NET Core در ویژوال استودیو ایجاد کنیم. با فرض اینکه Visual Studio 2022 در سیستم شما نصب شده است، مراحل ذکر شده در زیر را دنبال کنید تا یک پروژه برنامه کاربردی کنسول NET Core جدید در Visual Studio ایجاد کنید.

  1. Visual Studio IDE را راه اندازی کنید.
  2. روی “ایجاد پروژه جدید” کلیک کنید.
  3. در پنجره “ایجاد پروژه جدید”، “Console App (.NET Core)” را از لیست الگوهای نمایش داده شده انتخاب کنید.
  4. بعدی را کلیک کنید.
  5. در پنجره “پیکربندی پروژه جدید خود”، نام و مکان پروژه جدید را مشخص کنید.
  6. بعدی را کلیک کنید.
  7. در پنجره “اطلاعات اضافی” که در ادامه نشان داده شده است، “NET 7.0 (Standard Term Support)” را به عنوان نسخه چارچوبی که می خواهید استفاده کنید انتخاب کنید.
  8. روی ایجاد کلیک کنید.
پایتون در شاخص محبوبیت زبان پیشتاز است

ما از این پروژه برنامه کاربردی کنسول NET 7 برای کار با نمونه کدهای نشان داده شده در بخش‌های بعدی این مقاله استفاده خواهیم کرد.

IAsync مزایای بی شمار

مزایای کلیدی IAsyncEnumerable شامل موارد زیر است:

  • پشتیبانی از جریان ناهمزمان: یک مجموعه سنتی مانند یک لیست یا IEnumerable نیاز دارد که همه عناصر از قبل در دسترس باشند. از سوی دیگر، IAsyncEnumerable، آیتم ها را به محض در دسترس قرار گرفتن، پخش جریانی می کند. استفاده از IAsyncEnumerable به ویژه در هنگام برخورد با مجموعه داده های بزرگ یا جریان های داده بلادرنگ که ممکن است همه داده ها از قبل در دسترس نباشند، مفید است. با IAsyncEnumerable، می توانید بدون نیاز به صبر کردن برای بارگیری کامل مجموعه داده، بلافاصله پردازش موارد را شروع کنید. هنگام کار با فیدهای داده بلادرنگ مانند قیمت‌های سهام یا به‌روزرسانی‌های رسانه‌های اجتماعی، که در آن اطلاعات جدید دائماً تولید می‌شود و باید به محض در دسترس بودن پردازش شوند، این انعطاف‌پذیری سودمند است.
  • استفاده کارآمد از منابع موجود: IAsyncEnumerable به شما امکان می‌دهد با توالی‌های بزرگی از داده‌ها به صورت ناهمزمان کار کنید، که تضمین می‌کند منابع محاسباتی ارزشمند هدر نمی‌روند.
  • عملکرد پیشرفته: IAsyncEnumerable می‌تواند عملکرد برنامه شما را با حذف نیاز به بارگیری همه داده‌ها در یک لحظه بهبود بخشد. در نتیجه، سیستم می تواند از حافظه کمتری استفاده کند و منابع را آزاد کند.
  • پاسخگویی بهبودیافته: با IAsyncEnumerable، می‌توانید به راحتی کدی بنویسید که جریان‌های بزرگی از داده‌ها را به صورت پاسخگو مدیریت کند. همچنین می‌توانید از منابع به‌طور مؤثرتری استفاده کنید و عملکرد کلی برنامه را بهبود بخشید، به طوری که برنامه شما حتی در هنگام کار با مجموعه داده‌های بزرگ پاسخگو باقی بماند.
  • کد ساده‌تر: IAsyncEnumerable کد را با حذف مکانیسم‌های همگام‌سازی پیچیده مانند قفل‌ها و سمافورها ساده‌تر می‌کند و در نتیجه احتمال بن‌بست و سایر مسائل مربوط به همگام‌سازی را در برنامه شما کاهش می‌دهد.
مجوز جاوا برای هر کارمند اوراکل می تواند به نفع رقبا باشد

در بخش بعدی، چند عملیات پیشرفته را که می‌توانید با استفاده از IAsyncEnumerable روی توالی‌های ناهمزمان داده‌ها انجام دهید، بررسی می‌کنیم.

فیلتر کردن با IAsyncEnumerable

قطعه کد زیر نشان می دهد که چگونه می توانید دنباله ای ناهمزمان از داده ها را فیلتر کنید تا فقط اعداد زوج را بازیابی کنید.

public async IAsyncEnumerable<int> GetEvenNumbersAsync(IEnumerable<int> integers)
{
    foreach (var n in integers)
    {
        await Task.Delay(500);
        if (n % 2 == 0)
        {
            yield return n;
        }
    }
}

تجمیع با IAsyncEnumerable

قطعه کد زیر نشان می دهد که چگونه می توانید از مزایای IAsyncEnumerable برای محاسبه مجموع اعداد صحیح در یک دنباله ناهمزمان از اعداد استفاده کنید.

public async Task<int> GetSumAsync(IEnumerable<int> integers)
{
    int sum = 0;
        await foreach (var n in GetNumbersAsync(integers))
    {
        sum += n;
    }
        return sum;
}

برگزاری ناهمزمان با IAsyncEnumerable

قطعه کد زیر نشان می دهد که چگونه می توانید از پیش بینی ها با IAsyncEnumerable استفاده کنید.

public async IAsyncEnumerable<int> GetNumbersUsingProjectionAsync(IEnumerable<int> integers)
{
    foreach (var n in integers)
    {
        await Task.Delay(500);
        yield return await Task.Run(() => n * 10);
    }
}

تبدیل یک دنباله با IAsyncEnumerable

قطعه کد زیر نشان می دهد که چگونه می توانید از مزایای IAsyncEnumerable برای تبدیل دنباله ای از اعداد و به دست آوردن مقادیر تبدیل شده استفاده کنید.

public async IAsyncEnumerable<string> TransformNumbersAsync(IEnumerable<int> integers)
{
    foreach (var n in integers)
    {
        await Task.Delay(500);
        yield return n.ToString();
    }
}

پردازش دسته ای با IAsyncEnumerable

علاوه بر واکشی اقلام در یک زمان، می توانید هنگام کار با IAsyncEnumerable نیز موارد را به صورت دسته ای پردازش کنید. این در قطعه کد زیر نشان داده شده است.

public static async IAsyncEnumerable<IEnumerable<T>> ProcessBatch<T>(IAsyncEnumerable<T> source, int size,
    CancellationToken cancellationToken = default)
{
    var batch = new List<T>();
    await foreach (var item in source)
    {
        if (cancellationToken.IsCancellationRequested)
            yield break;
        batch.Add(item);
        if (batch.Count >= size)
        {
            yield return batch;
            batch = new List<T>();
        }
    }
    if (batch.Count > 0)
    {
        yield return batch;
    }
}

بافر با IAsyncEnumerable

همچنین می‌توانید از بافر برای عملکرد بهتر در پردازش موارد به صورت ناهمزمان استفاده کنید.

public static async IAsyncEnumerable<T> ProcessBuffer<T>(this IAsyncEnumerable<T> source, int size,
    CancellationToken cancellationToken = default)
    {
        var queue = new Queue<T>();
        await foreach (var item in source)
        {
            if (cancellationToken.IsCancellationRequested)
                yield break;
            queue.Enqueue(item);
            while (queue.Count >= size)
            {
                yield return queue.Dequeue();
            }
        }
        while (queue.Count > 0)
        {
            yield return queue.Dequeue();
        }
    }

نتیجه گیری

همانطور که دیدیم، IAsyncEnumеrable چندین ویژگی قدرتمند را ارائه می‌کند که می‌توانند برای توالی‌های ناهمزمان اعمال شوند. علاوه بر این، می‌توانید از IAsyncEnumerable با عملگرهای LINQ برای انجام عملیات‌های مختلفی استفاده کنید که شامل فیلتر کردن، تبدیل، و جمع‌آوری مجموعه‌های داده بزرگ می‌شود، اما محدود به آن نیست. همچنین می‌توانید خطاهای زمان اجرا را که ممکن است هنگام کار با IAsyncEnumerable رخ دهد، مدیریت کنید، و می‌توانید از تلاش‌های مجدد استفاده کنید و گزارش‌گیری را پیاده‌سازی کنید تا چنین خطاهایی را به‌خوبی مدیریت کنید.