درخواست های ارتباط
جستجو
لیست دوستان من
صندوق پیام
همه را دیدم
  • در حال دریافت لیست پیام ها
صندوق پیام
رویدادها
همه را دیدم
  • در حال دریافت لیست رویدادها
همه رویدادهای من
تخفیف های وب سایت
همه تخفیف ها

عضویت در

کانال تلگرام

توسینسو

اطلاعات مطلب
مدرس/نویسنده
حسین احمدی
امتیاز: 216285
رتبه:3
344
265
418
2848
حسین احمدی ، بنیانگذار TOSINSO ، توسعه دهنده وب و برنامه نویس ، بیش از 12 سال سابقه فعالیت حرفه ای در سطح کلان ، مشاور ، مدیر پروژه و مدرس نهادهای مالی و اعتباری ، تخصص در پلتفرم دات نت و زبان سی شارپ ، طراحی و توسعه وب ، امنیت نرم افزار ، تحلیل سیستم های اطلاعاتی و داده کاوی ... پروفایل کاربر

برنامه نویسی Parallel در سی شارپ :: کوئری های Parallel در LINQ

تاریخ 34 ماه قبل
نظرات 0
بازدیدها 836
علاوه بر مواردی که تا کنون پیرامون برنامه نویسی Parallel در دات نت آموختیم امکان نوشتن کوئری های LINQ به صورت Parallel نیز وجود دارد. این قابلیت بوسیله یکسری Extension Method که برای این موضوع تعریف شده امکان پذیر است و اصطلاحاً به کوئری های LINQ که به صورت Parallel اجرا می شوند PLINQ گفته می شود.
اما شیوه اجرای کوئری ها به صورت Parallel چگونه است؟ زمانی که شما از متدهای مربوطه برای اجرای کوئری ها به صورت Parallel استفاده می کنید، PLINQ کوئری مورد نظر را آنالیز کرده و تصمیم میگیرد که اجرای کوئری به صورت Parallel بر روی Performance برنامه شما تاثیر منفی می گذارد یا خیر. کوئری که به صورت Parallel اجرا نشود اصطلاحاً Sequentional گفته می شود و PLINQ به صورت هوشمند نوع اجرای مناسب را برای کوئری شما انتخاب می کند، این موضوع به این معنی است که درخواست اجرای کوئری به صورت Parallel لزوماً تضمینی بر اجرای آن به صورت Parallel نیست و تصمیم این موضوع با آنالیزوری است که کوئری را تحلیل می کند.
متدهای مورد نیاز برای اجرای کوئری ها به صورت Parallel در کلاسی به نام ParallelEnumerable که در فضای نام System.LINQ قرار گرفته تعریف شده اند. در زیر ابتدا نگاهی به این متدها می اندازیم:

  1. متد AsParallel: این متد مشخص می کند که کوئری های بعد از این متد می بایست به صورت Parallel اجرا شوند.
  2. متد WithCancellation: مشخص می کند که در زمان اجرای کوئری به صورت دائم می بایست وضعیت token مشخص شده بررسی شده و در صورت درخواست Cancel کردن کوئری، روند اجرای آن متوقف شود.
  3. متد WithDegreeOfParallelism: مشخص می کند که چه تعداد پردازشگر باید برای اجرای کوئری تخصیص داده شود.
  4. متد ForAll: برای خروجی وضعیتی را فعال می کند که خروجی قبل از ادغام و بازگرداندن آن به Thread اصلی می بایست به صورت Parallel مورد پردازش تکمیلی قرار گیرد، دقیقاً مانند زمانی که نتیجه خروجی یک کوئری LINQ بوسیله دستور foreach مورد پردازش قرار می گیرد.

برای اینکه به صورت عملی با نحوه نوشتن کوئری های LINQ به صورت Parallel آشنا شویم مثال زیر را در نظر بگیرید:

static void Main(string[] args)
{
    Task.Factory.StartNew(ProcessData);

    Console.ReadKey();
}

public static void ProcessData()
{
    var source = Enumerable.Range(1, 1000000).ToArray();

    var evenNumbers = (from number in source where number%2 == 0 orderby number descending select number).ToArray();

    Console.WriteLine("Found {0} even numbers in source.", evenNumbers.Length);
}

در مثال بالا و در متد ProcessData، ابتدا بوسیله متد Range از کلاس Enumerable یک آرایه از اعداد 1 تا 1000000 ایجاد کردیم و در قدم بعدی بوسیله یک کوئری LINQ اعداد زوج را بدست آوردیم و در نهایت در خروجی تعداد اعداد زوج که بوسیله کوئری استخراج شده اند را در خروجی نمایش دادیم. اما اگر بخواهیم کوئری بالا به صورت Parallel اجرا شود می بایست بوسیله کوئری LINQ را به صورت زیر تغییر دهیم و از متد AsParallel استفاده کنیم:

var evenNumbers = (from number in source.AsParallel() where number%2 == 0 orderby number descending select number).ToArray();

همانطور که مشاهده می کنید، بعد از نوشتن منبع یعنی source از متد AsParallel برای اجرای کوئری به صورت Parallel استفاده کردیم.


Cancel کردن یک کوئری PLINQ


برای اینکه به کاربر قابلیت کنسل کردن کوئری ها را بدهیم از متد WithCancellation استفاده می کنیم، در ابتدا باید یک شئ از CancellationTokenSource ایجاد کنیم:

private static CancellationTokenSource tokenSource = new CancellationTokenSource();

در قدم بعدی به صورت زیر که در قسمت قبلی آموختیم مکانیزم کنسل کردن کوئری را آموزش می دهیم:

static void Main(string[] args)
{
    Task.Factory.StartNew(ProcessData);
    Console.CancelKeyPress += (sender, eventArgs) =>
    {
        eventArgs.Cancel = true;
        tokenSource.Cancel();
    };
    Console.ReadKey();
}

و در نهایت کد مربوط به کوئری را به صورت زیر تغییر می دهیم:

public static void ProcessData()
{
    var source = Enumerable.Range(1, 1000000).ToArray();

    int[] evenNumbers;

    try
    {
        evenNumbers = (from number in source.AsParallel().WithCancellation(tokenSource.Token) where number%2 == 0 orderby number descending select number).ToArray();
        Console.WriteLine("Found {0} even numbers in source.", evenNumbers.Length);
    }
    catch (OperationCanceledException ex)
    {
        Console.WriteLine(ex);
    }

}

همانطور که مشاهده می کنید در قسمت کوئری و بعد از متد AsParallel از متد WithCancellation برای مشخص کردن token تعریف شده که بواسطه آن کوئری را کنسل می کنیم استفاده کردیم. همچنین قسمت کوئری اصلی را داخل بدنه try..catch گذاشتیم، زیرا در صورت فراخوانی متد Cancel برای شئ tokenSource، کوئری به صورت خودکار خطای OperationCanceledException را تولید می کند (با این مکانیزم در قسمت قبلی آموزش آشنا شدیم.)

با اتمام این بخش مباحث مرتبط با TPL در دات نت نیز به پایان رسید، البته مطالب مرتبط با TPL بسیار گسترده بوده و شاید برای پوشش کل مباحث مرتبط نیاز به نوشتن صدها صفحه مطلب باشد، اما کلیت موضوع را سعی کردیم در این سری مطالب مطرح کنیم. در قسمت بعدی که قسمت نهایی سری مطالب Asynchronous Programming است با کلمات کلیدی async و await که روش ساده تری برای نوشتن برنامه های Asynchronous در اختیار ما قرار می دهند آشنا می شویم. ITPRO باشید

نویسنده: حسین احمدی
منبع: ITPRO
برچسب ها
ردیف عنوان
1 کار با Thread ها در زبان سی شارپ :: آشنایی با Process ها، Thread ها و AppDomain ها
2 کار با Thread ها در زبان سی شارپ :: آشنایی با ماهیت Asynchronous در Delegate ها
3 کار با Thread ها در زبان سی شارپ :: آشنایی با فضای نام System.Threading و کلاس Thread
4 کار با Thread ها در زبان سی شارپ :: آشنایی با Thread های Foreground و Background در دات نت
5 کار با Thread ها در زبان سی شارپ :: آشنایی با مشکل Concurrency در برنامه های Multi-Threaded و راهکار های رفع این مشکل
6 کار با Thread ها در زبان سی شارپ :: آشنایی با کلاس Timer
7 کار با Thread ها در زبان سی شارپ :: آشنایی با CLR ThreadPool در دات نت
8 برنامه نویسی Parallel در سی شارپ :: مقدمه ای بر Task Parallel Library و کلاس Parallel در دات نت
9 برنامه نویسی Parallel در سی شارپ :: آشنایی با کلاس Task در سی شارپ
10 برنامه نویسی Parallel در سی شارپ :: متوقف کردن Task ها در سی شارپ - کلاس CancellationToken
11 برنامه نویسی Parallel در سی شارپ :: کوئری های Parallel در LINQ
12 آشنایی با کلمات کلیدی async و await در زبان سی شارپ
13 استفاده از متد WhenAll برای اجرای چندین Task به صورت همزمان در سی شارپ
دوره مجموعه کل دوره
مطالب مرتبط

در حال دریافت اطلاعات

نظرات
هیچ نظری ارسال نشده است

    برای ارسال نظر ابتدا به سایت وارد شوید