الخميس، 25 يوليو 2013

دورة الدوت نت الدرس(16): مدخل لمسارات التنفيذ Threading


دورة الدوت نت
الدرس(16): مدخل لمسارات التنفيذ Threading
السلام عليكم ورحمة الله وبركاته
 في هذا الدرس سنتطرق لموضوع نال أهمية واضحة في عالم الدوت نت
 سأتطرق لعدة أمثلة توضح مضمون درسنا لهذا اليوم إن شاء الله


 لنأخذ مثلا برنامج الوورد.. نعرف جميعا أن برنامج الوورد يقوم بعملية التدقيق الإملائي وعند كتابة أي كلمة يقوم الورد بالبحث عنها في معجمه وإن لم يجدها يخبرك بأنها خاطئة
 في الحقيقة عملية البحث في معجم يحتوي على كم هائل من الكلمات عملية ليست بالبسيطة وتستغرق وقت ومصادر ليست بالقليلة.. وإن كان الأمر أن يقوم البرنامج بعملية تدقيق بعد كل حرف - وهذا ما يحدث فعلا - بتفكيرنا وعلمنا الضيق بواسطة برنامج واحد لمكثنا وقتا طويلا في كتابة جملة واحدة فقط وهنا تأتي فكرة التطبيقات متعددة مسارات التنفيذ
 حيث تم إنشاء مسار خاص بالمدقق وحده بشكل لا يؤثر على عمل البرنامج.

 إن لم تتضح الفكرة بالمثال السابق لنتناول المثال التالي:
 مضادات الفيروسات تقوم بالكثير من المهام في نفس الوقت ( مراقبة المنافذ وفحص الملفات و تحديثات للبرنامج ووو)
 من البديهي جدا أن كل ذلك لا يتم في مسار واحد وإلا لما استطاع البرنامج القيام بهذه المهام في ذات الوقت.


 الآن أتمنى أن تكون الفكرة قد وصلت ولندخل لموضوعنا بإذن الله.

 في بادئ الأمر دعني أناقش معك المثال التالي من باب التوضيح:
 الآن قم بانشاء مشروع جديد وضع فيه بوتون واحد وأداة Label وأداة تايمر
 دعنا نقوم بعملية ربط نصوص في حلقة تكرارية ل 100000 مرة.
كود:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim MyString  As String = ""
        For I = 0 To 100000
            MyString &= "o"
        Next

End Sub


 نفذ البرنامج واضغط على البوتون الذي وضعته.
 ستجد أن البرنامج توقف عن الاستجابة لثوان عديدة مما سيثير استفزاز المستخدم
 وسبب التوقف - لم يتوقف فعلا - أن البرنامج مشغول ب100000 عملية ربط نصوص
 لتفادي هذه المشكلة دعنا نجعل تنفيذ عملية الربط في مسار آخر حتى لا يؤثر ذلك على عمل البرنامج ومن هنا يستدعي الأمر الإعلان عن Thread جديد
 في البداية قم باستيراد مجال الأسماء System.Threading
كود:
             Imports System.Threading 


 الآن نقوم بتعريف كائن جديد من نوع Thread

كود:
                                     Dim NewThread As New Thread(AddressOf DoIt( 
تجد أنه من الضروري تمرير وسيط باستخدام الكلمة المحجوزة AddressOf وفي المثال التعليمة السابقة مررنا له إجراء DoIt

 وهذا الإجراء الذي قمنا بتمريره قبل قليل
كود:
 Sub DoIt()
        For I = 0 To 100000
            MyString &= "o"
        Next

        NewThread.Abort()
    End Sub


تجد أننا قمنا بعملية الربط داخل الإجراء DoIt

 لتنفيذ الThread الذي أعلنا عنه (NewThread) استخدم الطريقة Start
كود:
             NewThread.Start()
الآن بعد تشغيل المسار الآخر دعنا نراقب ما وصلت إليه عملية الربط باستخدام تايمر جديد

 وهذا الكود بشكله النهائي للمثال الأخير لربط المفاهيم بعضها ببعض
كود:
   Dim MyString As String = ""
    Dim NewThread As New Threading.Thread(AddressOf DoIt(
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        NewThread.Start()
        Button1.Enabled = False
    End Sub

   

    Sub DoIt()
        For I = 0 To 100000
            MyString &= "o"
        Next
        NewThread.Abort()
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Label1.**** = MyString.Length
    End Sub

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Timer1.Enabled = True
    End Sub



 بهذا إن شاء الله نكون أتممنا توضيح مفهوم الThreads

 نأتي الآن لطرق الThread

Start

 وهي إشارة لبدء تنفيذ الThread
كود:
                                     NewThread.Start() 



Abort

 وهي لإحباط و إيقاف ال Thread
كود:
                                     NewThread.Abort() 



Suspend

 وهي للإيقاف المؤقت لل Tread
كود:
                                     NewThread.Suspend() 

Resume

 وهي لمتابعة الThread بعد اللإيقاف المؤقت له
كود:
                                     NewThread.Resume() 



Sleep

 وهي لايقاف الThread بشكل مؤقت لفترة زمنية تقوم بتحديدها
كود:
                                     NewThread.Sleep(1000)  Will Suspend for 1 second 


 يمكننا التحكم بالمسار الحالي من خلال
كود:
                                     Thread.CurrentThread 
 مثال:
كود:
                                     Thread.CurrentThread.Abort() 


 ونأتي لخاصية من خواص الThread
 IsAlive()
كود:
If NewThread.IsAlive() Then
''Statements
End If

 قرأت عبارة في كتاب الاستاذ تركي العسيري طريفة
كود:
من الغباء الاستعلام عن الخاصية IsAlive لمسار التنفيذ الحالي:
 If Thread.CurrentThread.IsAlive() Then ......
 فهي ستعود بالقيمة True دائما لأسباب منطقية .
طبعا تعرفوا السبب !

 أيضا يمكن إسناد اسم لكل مسار تنفيذ ما يساعدك على مراقبة عمل برنامج بدقة
كود:
                                     NewThread.Name = "My Thread" 
 أيضا يمكنك معرفة حالة الThread باستخدام الخاصية ThreadState
كود:
                                     If NewThread.ThreadState = ThreadState.Running Then..... 


 والحالات التي يمكن أن تصادف الThread هي
ThreadState.Aborted
 ThreadState.AbortRequested
 ThreadState.Background
 ThreadState.Running
 ThreadState.Stopped
 ThreadState.StopRequested
 ThreadState.Suspended
 ThreadState.SuspendRequested
 ThreadState.Unstarted
 ThreadState.WaitSleepJoin


 نأتي لنقطة أخيرة في فصلنا لهذا اليوم
 يمكن تعيين الأفضلية للمسارات باستخدام الخاصية Priority
 وبها خمس تعيينات

الأقل
أقل من العادي
عادي
أكثر من العادي
الأكثر
مع تحياتي عبدالقادر البعداني

 بهذا نتمم درسنا لهذا اليوم


ليست هناك تعليقات:

إرسال تعليق