بسم الله الرحمن الرحيم
مبروك علينا جميعاً عودة المنتدى بخير
ندخل في الموضوع
هل جربت من قبل أن تتعامل مع الThreads ؟؟؟؟
اذا كانت اجابتك بلا فاقرأ معي هذا الموضوع و اذا كانت اجابتك بنعم فقرأه أيضاً ففيه فائدة عظيمة ستجدها بين سطور الموضوع
هل ترى التعامل مع الThreads صعب ؟؟؟؟
هو ليس صعباً و لكنه فقط مرحلة أخرى متقدمة و لا يجب أن تكون كل مرحلة متقدمة صعبة و العكس صحيح فأحيانا البداية تكون الأصعب على الاطلاق
ما هي الThreads ؟
الThreads هي محاولة تجزئة البرنامج الى مجموعة من العمليات المستقلة و التي يمكن أداءها بطريقة متوازية Parallel بدلاً من اضاعة الوقت في انتظار لا طائل منه و هو النظام المتسلسل Serial Execution و يهدف النظام الى تحسين أداء البرامج عموماً فاذا تخيلنا مثلاً برنامجأ رياضياً يقوم بعمل حسابات طويلة و معقدة (Matlab مثلاً) فان البرنامج أثناء تنفيذ هذه العمليات لا يمكنه اداء اي مهمة اخرى حتى ينتهي من الحسابات و من مساوئ هذا هو عدم استجابة البرنامج الى المستخدم (بالبلدي الشاشة بتهنج)...
و لكن هل هذا مانراه فعلاً في البرامج الحقيقية؟؟؟
بالطبع لا فبرنامج Matlab مثلاً يمكتك من تشغيل برامجك و كتابة برامج أخرى و التفاعل مع واجهاته في نفس الوقت بدون أي مشاكل و هذا لأن جميع هذه العمليات هي عمليات مستقلة يمكن التعامل معها من خلال البرنامج بطريقة متوازية
هل الThreading مفهوم جديد
الThreading بصفة عامة مفهوم معروف و لكن للأسف لم يتم تطبيقه على مستوى لغات البرمجة بل تُرك مفتوحاً لكل نظام يطبقه كما يشاء و يدعم ما يريد و هذا ما جعل الThreading في ال++C مثلاً من المواضيع السيئة فكل نظام له الAPI's الخاصة به و التي تختلف كلياً عن أي نظام اخر...
و لكن مع ظهور الأجيال الحديثة من لغات البرمجة بدأً من الJAVA و التي حسب معلوماتي أول لغة ظهر الThreading فيها كجزء من اللغة نفسها بحيث أنتقلت مشاكل التعامل مع النظام و طريقة تطبيق الThreading نفسها الى الJVM بدلاً من المبرمج المسكين...
و بالطبع مع ظهور ال.net كان الThreading جزء لا يتجزأ من الFramework و يمكن استخدامه من أي لغة تتبع الCLR ..
اذاً كيف نقوم بعمل Threading في ال#C ؟؟؟
أولاً هناك Namespace تختص بالThreading و هي System.Threading و هي تحتوي على جميع الclasses الخاصة بالThreading....
اذاً فأول سطر في برنامج يتعامل مع الThreading هو
using System.Threading
أهم Class في الThreading بالطبع هي System.Threading.Thread و هي التي توجد فيها أغلب العمليات الأساسية
اذاً هل الخطوة الثانية هي انشاء object من نوع Thread ؟؟
الحقيقة هذه الخطوة تسبقها خطوة قبلها و هي كتابة الfunction التي ستقوم هذه الThread بتنفيذها و لتكن مثلاً
void PrintHello()
{
Console.WriteLine("Hello Threading...");
}ثم نقوم بعمل الObject من نوع Thread
Thread thread = new Thread(new ThreadStart(PrintHello));
ثانية واحدة ايه اللي انت كاتبه ده ؟؟؟؟ مين ThreadStart دي و ازاي كاتب اسم الfunction كأنه parameter ؟؟؟؟
لو سألت نفسك السؤال السابق اذن فأنت أول مرة تتعامل مع الDelegates و هي باختصار شديد بديل محترم لما كنا نستخدمه في ال++C/C و هو الFunction Pointer ...
الحقيقة المجال لا يتسع لشرح الDelegate هنا و لكن يمكنك أن ترجع للMSDN أو ابحث في المنتدى... و لو مستعجل كل اللي محتاج تعرفه في السطر اللي فات اني بقول للThread بتاعتي ان الfunction اللي حتنفذها اسمها PrintHello
شفت خرجتني من الموضوع ازاي؟؟؟ :angry: على العموم ما علينا
بقيت خطوة أخرى و هي تشغيل الThread نفسها باضافة سطر اخر
thread.Start();
هي دي الThreads بقة و عاملين الهوليلا دي على ال 3 سطور دول؟
لأ طبعاً دي البداية بس الموضوع طويل و فيه كلام كبير صحصح معايا كده لسة التقيل ورا
طيب هل هذه هي الطريقة الوحيدة لانشاء Threads
الاجابة بالطبع لا و لكن توجد طرق أخرى كثيرة و هناك أيضاً طرق يتم فيها انشاء Threads بواسطة النظام دون أن يدخل المبرمج في تفاصيل انشاء الThreads و هي ما يسمى بالAsynchronous Operations و ستجد الكثير منها في الdotnet فمبدئيأ أي عملية تبدأ بكلمة BeginْXXX و يوجد لها مثيل يبدأ بEndXXX تعتبر عمليات غير متزامنه و مثال على هذا في الStreams ستجد BeginRead و EndRead و أيضاً BeginWrite و EndWrite و هذا موضوع اخر مثير في الdotnet و سأحاول شرحه لاحقاً
و يوجد أيضاً طريقة أخرى لانشاء الThreads و تعتمد على فكرة أن انشاء Thread جديدة و تشغيلها و مايتطلبه هذا من بعض العمليات الأخرى أحياناً يكون وقت هذه العمليات أكبر من العملية التي ستنفذها الThread في النهاية مما يؤثر سلباً على الأداء و هنا ظهر مفهوم الThreadPool أي مستودع الThreads و هي مجموعة من الThreads المنشأة (بضم الميم) مسبقاً و هي جاهزة و تحتاج فقط للعملية التي ستقوم بها و يكون لها عدد مُحدد و يمكن للمستخدم أن يستخدمها ببساطة جداً
طريقة استخدامها تكون من الThreadPool Class عن طريق وضع الfunction المُراد تنفيذها في الQueue حتى تفرغ احدى الThreads لتنفيذ هذه العملية و يكون هكذا
ThreadPool.QueueUserWorkItem(new WaitCallback(PrintHello));
و هكذا سيتم وضع العملية في الQueue و سيكمل البرنامج عمله دون انتظار و عندما تكون هناك Thread جاهزة سيتم التنفيذ
هل الحياة وردية دائماً في الThreading ؟؟؟؟
بالطبع لا و توجد مشاكل عديدة و سيكون مقالي التالي عن المشاكل الشهيرة و الشائعة و طرق تفاديها ....
سلام ;)
