23-09-12, 06:46 PM
السلام عليكم ورحمة الله وبركاته
في هذا الفصل سنتطرق لموضوع نال أهمية واضحة في عالم الدوت نت
سأتطرق لعدة أمثلة توضح مضمون فصلنا لهذا اليوم إن شاء الله
ملاحظة : بعض الأمثلة اقتبستها من مصادر أخرى لوضوحها
لنأخذ مثلا برنامج الوورد.. نعرف جميعا أن برنامج الوورد يقوم بعملية التدقيق الإملائي وعند كتابة أي كلمة يقوم الورد بالبحث عنها في معجمه وإن لم يجدها يخبرك بأنها خاطئة
في الحقيقة عملية البحث في معجم يحتوي على كم هائل من الكلمات عملية ليست بالبسيطة وتستغرق وقت ومصادر ليست بالقليلة.. وإن كان الأمر أن يقوم البرنامج بعملية تدقيق بعد كل حرف - وهذا ما يحدث فعلا - بتفكيرنا وعلمنا الضيق بواسطة برنامج واحد لمكثنا وقتا طويلا في كتابة جملة واحدة فقط وهنا تأتي فكرة التطبيقات متعددة مسارات التنفيذ
حيث تم إنشاء مسار خاص بالمدقق وحده بشكل لا يؤثر على عمل البرنامج.
إن لم تتضح الفكرة بالمثال السابق لنتناول المثال التالي:
مضادات الفيروسات تقوم بالكثير من المهام في نفس الوقت ( مراقبة المنافذ وفحص الملفات و تحديثات للبرنامج ووو)
من البديهي جدا أن كل ذلك لا يتم في مسار واحد وإلا لما استطاع البرنامج القيام بهذه المهام في ذات الوقت.
الآن أتمنى أن تكون الفكرة قد وصلت ولندخل لموضوعنا بإذن الله.
في بادئ الأمر دعني أناقش معك المثال التالي من باب التوضيح:
الآن قم بانشاء مشروع جديد وضع فيه بوتون واحد وأداة Label وأداة تايمر
دعنا نقوم بعملية ربط نصوص في حلقة تكرارية ل 100000 مرة.
نفذ البرنامج واضغط على البوتون الذي وضعته.
ستجد أن البرنامج توقف عن الاستجابة لثوان عديدة مما سيثير استفزاز المستخدم
وسبب التوقف - لم يتوقف فعلا - أن البرنامج مشغول ب100000 عملية ربط نصوص
لتفادي هذه المشكلة دعنا نجعل تنفيذ عملية الربط في مسار آخر حتى لا يؤثر ذلك على عمل البرنامج ومن هنا يستدعي الأمر الإعلان عن Thread جديد
في البداية قم باستيراد مجال الأسماء System.Threading
الآن نقوم بتعريف كائن جديد من نوع Thread
تجد أنه من الضروري تمرير وسيط باستخدام الكلمة المحجوزة AddressOf وفي المثال التعليمة السابقة مررنا له إجراء DoIt
وهذا الإجراء الذي قمنا بتمريره قبل قليل
تجد أننا قمنا بعملية الربط داخل الإجراء DoIt
لتنفيذ الThread الذي أعلنا عنه (NewThread) استخدم الطريقة Start
الآن بعد تشغيل المسار الآخر دعنا نراقب ما وصلت إليه عملية الربط باستخدام تايمر جديد
وهذا الكود بشكله النهائي للمثال الأخير لربط المفاهيم بعضها ببعض
بهذا إن شاء الله نكون أتممنا توضيح مفهوم الThreads
نأتي الآن لطرق الThread
يمكننا التحكم بالمسار الحالي من خلال
مثال:
ونأتي لخاصية من خواص الThread
IsAlive()
قرأت عبارة في كتاب الاستاذ تركي العسيري طريفة
طبعا تعرفوا السبب !
أيضا يمكن إسناد اسم لكل مسار تنفيذ ما يساعدك على مراقبة عمل برنامج بدقة
أيضا يمكنك معرفة حالة الThread باستخدام الخاصية ThreadState
والحالات التي يمكن أن تصادف الThread هي
نأتي لنقطة أخيرة في فصلنا لهذا اليوم
يمكن تعيين الأفضلية للمسارات باستخدام الخاصية Priority
وبها خمس تعيينات
بهذا نتمم فصلنا لهذا اليوم
والسلام عليكم
إخوانكم Lo2i و Mohammed Asaad
في هذا الفصل سنتطرق لموضوع نال أهمية واضحة في عالم الدوت نت
سأتطرق لعدة أمثلة توضح مضمون فصلنا لهذا اليوم إن شاء الله
ملاحظة : بعض الأمثلة اقتبستها من مصادر أخرى لوضوحها
لنأخذ مثلا برنامج الوورد.. نعرف جميعا أن برنامج الوورد يقوم بعملية التدقيق الإملائي وعند كتابة أي كلمة يقوم الورد بالبحث عنها في معجمه وإن لم يجدها يخبرك بأنها خاطئة
في الحقيقة عملية البحث في معجم يحتوي على كم هائل من الكلمات عملية ليست بالبسيطة وتستغرق وقت ومصادر ليست بالقليلة.. وإن كان الأمر أن يقوم البرنامج بعملية تدقيق بعد كل حرف - وهذا ما يحدث فعلا - بتفكيرنا وعلمنا الضيق بواسطة برنامج واحد لمكثنا وقتا طويلا في كتابة جملة واحدة فقط وهنا تأتي فكرة التطبيقات متعددة مسارات التنفيذ
حيث تم إنشاء مسار خاص بالمدقق وحده بشكل لا يؤثر على عمل البرنامج.
إن لم تتضح الفكرة بالمثال السابق لنتناول المثال التالي:
مضادات الفيروسات تقوم بالكثير من المهام في نفس الوقت ( مراقبة المنافذ وفحص الملفات و تحديثات للبرنامج ووو)
من البديهي جدا أن كل ذلك لا يتم في مسار واحد وإلا لما استطاع البرنامج القيام بهذه المهام في ذات الوقت.
الآن أتمنى أن تكون الفكرة قد وصلت ولندخل لموضوعنا بإذن الله.
في بادئ الأمر دعني أناقش معك المثال التالي من باب التوضيح:
الآن قم بانشاء مشروع جديد وضع فيه بوتون واحد وأداة Label وأداة تايمر
دعنا نقوم بعملية ربط نصوص في حلقة تكرارية ل 100000 مرة.
كود :
[align=left]
[color=#000000][COLOR=#007700]Private [/color][color=#0000BB]Sub Button1_Click[/color][color=#007700]([/color][color=#0000BB]ByVal sender [/color][color=#007700]As [/color][color=#0000BB]System[/color][color=#007700].[/color][color=#0000BB]Object[/color][color=#007700], [/color][color=#0000BB]ByVal e [/color][color=#007700]As [/color][color=#0000BB]System[/color][color=#007700].[/color][color=#0000BB]EventArgs[/color][color=#007700]) [/color][color=#0000BB]Handles Button1[/color][color=#007700].[/color][COLOR=#0000BB]Click
Dim MyString [/COLOR][color=#007700]As [/color][color=#0000BB]String [/color][color=#007700]= [/color][COLOR=#DD0000]""
[/COLOR][color=#007700]For [/color][color=#0000BB]I [/color][color=#007700]= [/color][COLOR=#0000BB]0 To 100000
MyString [/COLOR][color=#007700]&= [/color][COLOR=#DD0000]"o"
[/COLOR][COLOR=#0000BB]Next
End Sub
[/COLOR][/COLOR][/align]
نفذ البرنامج واضغط على البوتون الذي وضعته.
ستجد أن البرنامج توقف عن الاستجابة لثوان عديدة مما سيثير استفزاز المستخدم
وسبب التوقف - لم يتوقف فعلا - أن البرنامج مشغول ب100000 عملية ربط نصوص
لتفادي هذه المشكلة دعنا نجعل تنفيذ عملية الربط في مسار آخر حتى لا يؤثر ذلك على عمل البرنامج ومن هنا يستدعي الأمر الإعلان عن Thread جديد
في البداية قم باستيراد مجال الأسماء System.Threading
كود :
[align=left] [color=#000000] [COLOR=#0000BB]Imports System[/color][color=#007700].[/color][COLOR=#0000BB]Threading
[/COLOR][/COLOR][/align]
الآن نقوم بتعريف كائن جديد من نوع Thread
كود :
[align=left][color=#000000][COLOR=#0000BB] [COLOR=#000000] [COLOR=#0000BB]Dim NewThread [/color][color=#007700]As New [/color][color=#0000BB]Thread[/color][color=#007700]([/color][color=#0000BB]AddressOf DoIt[/color][color=#007700]) [/color][/COLOR]
[/COLOR][/COLOR][/align]
تجد أنه من الضروري تمرير وسيط باستخدام الكلمة المحجوزة AddressOf وفي المثال التعليمة السابقة مررنا له إجراء DoIt
وهذا الإجراء الذي قمنا بتمريره قبل قليل
كود :
[align=left][color=#000000][COLOR=#0000BB] Sub DoIt[/color][COLOR=#007700]()
For [/COLOR][color=#0000BB]I [/color][color=#007700]= [/color][COLOR=#0000BB]0 To 100000
MyString [/COLOR][color=#007700]&= [/color][COLOR=#DD0000]"o"
[/COLOR][COLOR=#0000BB]Next
NewThread[/COLOR][color=#007700].[/color][color=#0000BB]Abort[/color][COLOR=#007700]()
[/COLOR][COLOR=#0000BB]End Sub
[/COLOR][/COLOR][/align]
تجد أننا قمنا بعملية الربط داخل الإجراء DoIt
لتنفيذ الThread الذي أعلنا عنه (NewThread) استخدم الطريقة Start
كود :
[align=left] [color=#000000] [COLOR=#0000BB]NewThread[/color][color=#007700].[/color][color=#0000BB]Start[/color][color=#007700]()[/color][/COLOR]
[/align]
الآن بعد تشغيل المسار الآخر دعنا نراقب ما وصلت إليه عملية الربط باستخدام تايمر جديد
وهذا الكود بشكله النهائي للمثال الأخير لربط المفاهيم بعضها ببعض
كود :
[align=left][color=#000000][COLOR=#0000BB] Dim MyString [/color][color=#007700]As [/color][color=#0000BB]String [/color][color=#007700]= [/color][COLOR=#DD0000]""
[/COLOR][color=#0000BB]Dim NewThread [/color][color=#007700]As New [/color][color=#0000BB]Threading[/color][color=#007700].[/color][color=#0000BB]Thread[/color][color=#007700]([/color][color=#0000BB]AddressOf DoIt[/color][COLOR=#007700])
Private [/COLOR][color=#0000BB]Sub Button1_Click[/color][color=#007700]([/color][color=#0000BB]ByVal sender [/color][color=#007700]As [/color][color=#0000BB]System[/color][color=#007700].[/color][color=#0000BB]Object[/color][color=#007700], [/color][color=#0000BB]ByVal e [/color][color=#007700]As [/color][color=#0000BB]System[/color][color=#007700].[/color][color=#0000BB]EventArgs[/color][color=#007700]) [/color][color=#0000BB]Handles Button1[/color][color=#007700].[/color][COLOR=#0000BB]Click
NewThread[/COLOR][color=#007700].[/color][color=#0000BB]Start[/color][COLOR=#007700]()
[/COLOR][color=#0000BB]Button1[/color][color=#007700].[/color][color=#0000BB]Enabled [/color][color=#007700]= [/color][COLOR=#0000BB]False
End Sub
Sub DoIt[/COLOR][COLOR=#007700]()
For [/COLOR][color=#0000BB]I [/color][color=#007700]= [/color][COLOR=#0000BB]0 To 100000
MyString [/COLOR][color=#007700]&= [/color][COLOR=#DD0000]"o"
[/COLOR][COLOR=#0000BB]Next
NewThread[/COLOR][color=#007700].[/color][color=#0000BB]Abort[/color][COLOR=#007700]()
[/COLOR][COLOR=#0000BB]End Sub
[/COLOR][color=#007700]Private [/color][color=#0000BB]Sub Timer1_Tick[/color][color=#007700]([/color][color=#0000BB]ByVal sender [/color][color=#007700]As [/color][color=#0000BB]System[/color][color=#007700].[/color][color=#0000BB]Object[/color][color=#007700], [/color][color=#0000BB]ByVal e [/color][color=#007700]As [/color][color=#0000BB]System[/color][color=#007700].[/color][color=#0000BB]EventArgs[/color][color=#007700]) [/color][color=#0000BB]Handles Timer1[/color][color=#007700].[/color][COLOR=#0000BB]Tick
Label1[/COLOR][color=#007700].[/color][color=#0000BB]**** [/color][color=#007700]= [/color][color=#0000BB]MyString[/color][color=#007700].[/color][COLOR=#0000BB]Length
End Sub
[/COLOR][color=#007700]Private [/color][color=#0000BB]Sub Form1_Load[/color][color=#007700]([/color][color=#0000BB]ByVal sender [/color][color=#007700]As [/color][color=#0000BB]Object[/color][color=#007700], [/color][color=#0000BB]ByVal e [/color][color=#007700]As [/color][color=#0000BB]System[/color][color=#007700].[/color][color=#0000BB]EventArgs[/color][color=#007700]) [/color][color=#0000BB]Handles Me[/color][color=#007700].[/color][COLOR=#0000BB]Load
Timer1[/COLOR][color=#007700].[/color][color=#0000BB]Enabled [/color][color=#007700]= [/color][COLOR=#0000BB]True
End Sub
[/COLOR][/COLOR][/align]
بهذا إن شاء الله نكون أتممنا توضيح مفهوم الThreads
نأتي الآن لطرق الThread
- Start
كود :
[align=left] [color=#000000] [COLOR=#0000BB]NewThread[/color][color=#007700].[/color][color=#0000BB]Start[/color][COLOR=#007700]()
[/COLOR][/COLOR][/align]
- Abort
كود :
[align=left] [color=#000000] [COLOR=#0000BB]NewThread[/color][color=#007700].[/color][color=#0000BB]Abort[/color][COLOR=#007700]()
[/COLOR][/COLOR][/align]
- Suspend
كود :
[align=left] [color=#000000] [COLOR=#0000BB]NewThread[/color][color=#007700].[/color][color=#0000BB]Suspend[/color][color=#007700]() [/color][/COLOR]
[/align]
- Resume
كود :
[align=left] [color=#000000] [COLOR=#0000BB]NewThread[/color][color=#007700].[/color][color=#0000BB]Resume[/color][COLOR=#007700]()
[/COLOR][/COLOR][/align]
- Sleep
كود :
[align=left] [color=#000000] [COLOR=#0000BB]NewThread[/color][color=#007700].[/color][color=#0000BB]Sleep[/color][color=#007700]([/color][color=#0000BB]1000[/color][color=#007700]) [/color][color=#0000BB]Will Suspend [/color][color=#007700]for [/color][COLOR=#0000BB]1 second
[/COLOR][/COLOR][/align]
يمكننا التحكم بالمسار الحالي من خلال
كود :
[align=left] [color=#000000] [COLOR=#0000BB]Thread[/color][color=#007700].[/color][COLOR=#0000BB]CurrentThread
[/COLOR][/COLOR][/align]
مثال:
كود :
[align=left] [color=#000000] [COLOR=#0000BB]Thread[/color][color=#007700].[/color][color=#0000BB]CurrentThread[/color][color=#007700].[/color][color=#0000BB]Abort[/color][COLOR=#007700]()
[/COLOR][/COLOR][/align]
ونأتي لخاصية من خواص الThread
IsAlive()
كود :
[color=#007700]If [/color][color=#0000BB]NewThread[/color][color=#007700].[/color][color=#0000BB]IsAlive[/color][color=#007700]() [/color][COLOR=#0000BB]Then
[/COLOR][color=#DD0000]''[/color][COLOR=#0000BB]Statements
End [/COLOR][COLOR=#007700]If
[/COLOR]
قرأت عبارة في كتاب الاستاذ تركي العسيري طريفة
كود :
من الغباء الاستعلام عن الخاصية IsAlive لمسار التنفيذ الحالي:[align=left] If Thread.CurrentThread.IsAlive() Then ......
[/align]
فهي ستعود بالقيمة True دائما لأسباب منطقية .
طبعا تعرفوا السبب !
أيضا يمكن إسناد اسم لكل مسار تنفيذ ما يساعدك على مراقبة عمل برنامج بدقة
كود :
[align=left] [color=#000000] [COLOR=#0000BB]NewThread[/color][color=#007700].[/color][color=#0000BB]Name [/color][color=#007700]= [/color][COLOR=#DD0000]"My Thread"
[/COLOR][/COLOR][/align]
أيضا يمكنك معرفة حالة الThread باستخدام الخاصية ThreadState
كود :
[align=left] [color=#000000] [COLOR=#0000BB][/color][color=#007700]If [/color][color=#0000BB]NewThread[/color][color=#007700].[/color][color=#0000BB]ThreadState [/color][color=#007700]= [/color][color=#0000BB]ThreadState[/color][color=#007700].[/color][color=#0000BB]Running Then[/color][COLOR=#007700].....
[/COLOR][/COLOR][/align]
والحالات التي يمكن أن تصادف الThread هي
ThreadState.Aborted
ThreadState.AbortRequested
ThreadState.Background
ThreadState.Running
ThreadState.Stopped
ThreadState.StopRequested
ThreadState.Suspended
ThreadState.SuspendRequested
ThreadState.Unstarted
ThreadState.WaitSleepJoin
ThreadState.AbortRequested
ThreadState.Background
ThreadState.Running
ThreadState.Stopped
ThreadState.StopRequested
ThreadState.Suspended
ThreadState.SuspendRequested
ThreadState.Unstarted
ThreadState.WaitSleepJoin
نأتي لنقطة أخيرة في فصلنا لهذا اليوم
يمكن تعيين الأفضلية للمسارات باستخدام الخاصية Priority
وبها خمس تعيينات
- الأقل
- أقل من العادي
- عادي
- أكثر من العادي
- الأكثر
بهذا نتمم فصلنا لهذا اليوم
والسلام عليكم
إخوانكم Lo2i و Mohammed Asaad