المشاركات : 2,523
المواضيع 707
الإنتساب : Sep 2012
السمعة :
48
الشكر: 91
تم شكره 1104 مرات في 297 مشاركات
كاتب الموضوع : BADRMEDIA
العنصر BackgroundWorker
أنه من العناصر الممتازة التنى جاءت به الدوت نت مع اصدار 2005 ولم يكن موجود من قبل
وهو امتداد لمفهوم عمل مسارات Threading لعمليات التطبيق الواحد
المشاركات : 2,523
المواضيع 707
الإنتساب : Sep 2012
السمعة :
48
الشكر: 91
تم شكره 1104 مرات في 297 مشاركات
الحدث DoWork هو الحدث الافتراضي للعنصر BackgroundWorker
وهو المسئول عن تنفيذ العملية - ويكتب تحته العملية Statement
كود :
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
' Statement
End Sub
======================================
عندما تريد تشغيل العنصر لكى يبدأ فى عمله تنادى عليه بالكود
كود :
Me.BackgroundWorker1.RunWorkerAsync()
=====================================
لنقوم بالمثال التالى لنجرب الأداة سوياً
اكتب هذا الكود تحت الحدث الافتراضى للعنصر
كود :
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
For i As Integer = 0 To 100
Beep()
If i = 99 Then i = 0
Next
End Sub
ضع زر Button واكتب له هذا الحدث
كود :
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.BackgroundWorker1.RunWorkerAsync()
End Sub
ضع مربع نص TextBox على الفورم
شغل التطبيق ونفذ الأمر Button
وابدأ اكتب فى TextBox
ستجد أن العملية التى تحت العنصر BackgroundWorker تعمل فى مسار دون تعطيل الفورم
بحيث يمكنك الكتابة فى مربع النص TextBox والتعامل مع الفورم عادى جداً
ملحوظة :
ربما كود اطلاق صوت Beep وعمل حلقة لا نهائية بعدم وصولها للرقم 100 كما فى المثال السابق ليس احترافي بصورة كاملة - لكن أردنا توضيح المثال بصورة بسيطة لكى نفهم عمل العنصر BackgroundWorker
المشاركات : 2,523
المواضيع 707
الإنتساب : Sep 2012
السمعة :
48
الشكر: 91
تم شكره 1104 مرات في 297 مشاركات
تعلمنا فى المشاركة السابقة عن تطبيق لعمل المسار لعملية محددة منفصلة
لكن ربما تريد أن تلغي هذه العلمية أثناء تنفيذها
هناك خاصية خاصة بذلك يجب ان تجعل قيمتها تساوى True لتمكنك من ذلك
أما من نافذة خصائص العنصر BackgroundWorker تجعل الخاصية WorkerSupportsCancellation تساوى True
أو بالكود أثناء تحميل الفورم
كود :
Me.BackgroundWorker1.WorkerSupportsCancellation = True
وليكن عندي هذه العملية
كود :
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
For I As Integer = 0 To 1000
If Me.BackgroundWorker1.CancellationPending Then
e.Cancel = True
Return
End If
System.Threading.Thread.Sleep(100)
Next
End Sub
لكي أشغل المسار نكتب كما نعرف
كود :
Me.BackgroundWorker1.RunWorkerAsync()
ولكي نلغيها نكتب
كود :
Me.BackgroundWorker1.CancelAsync()
لكن لابد الخاصية تساوي True
كود :
Me.BackgroundWorker1.WorkerSupportsCancellation = True
المشاركات : 2,523
المواضيع 707
الإنتساب : Sep 2012
السمعة :
48
الشكر: 91
تم شكره 1104 مرات في 297 مشاركات
الآن سنقوم بشئ جديد
هل فكرت تربط أداة ProgressBar بمسار عملية ومدى تنفيذه
لنري ذلك
ضع أداة ProgressBar وزر Button على الفورم - بالطبع أيضاً عنصر BackgroundWorker
فى الحدث الافتراضي للعنصر نكتب هذا الكود
كود :
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
For I As Integer = 0 To 100
Me.BackgroundWorker1.ReportProgress(I)
System.Threading.Thread.Sleep(100)
Next
End Sub
هذا الكود نوضحه الآن
قمنا بعمل حلقة من إلى 100
نرسل إلي ReportProgress قيمة المتغير I وهو يبدأ من 0 حتى 100 وهى مدي نسبة تمام العملية
أوضحنا للمسار Threading وقت TimeOut لكى يتم حجب المسار لو تعداه
ويجب وضعه ويكون بالملى ثانية لأن فى حالة عدم وضعه يكون الافتراضي له صفر
كود :
System.Threading.Thread.Sleep(100)
حتى الأن الأمور واضحة
===========================================
نضع هذه الخصائص فى حدث تحميل الفورم
كود :
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.BackgroundWorker1.WorkerReportsProgress = True
Me.ProgressBar1.Minimum = 0
Me.ProgressBar1.Maximum = 100
End Sub
وهى تحديد خاصية Minimum - Maximum للأداة ProgressBar
جعلنا الخاصية WorkerReportsProgress للعنصر BackgroundWorker تساوي true لكى نستطيع أن نعود بقيمة نسبة تمام العملية
الخصائص السابقة يمكن تعديها أثناء وقت التصميم من نافذة الخصائص لكل أداة
=======================================
الحدث ProgressChanged للعنصر BackgroundWorker
سنجعله يرسل قيمة نسبة التمام إلى قيمة ProgressBar لكى يتغير قيمة ProgressBar مع نسبة تمام العملية
كود :
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Me.ProgressBar1.Value = e.ProgressPercentage
End Sub
===========================================
الآن وبعد طول شرح وانتظار نبدأ على بركة الله اطلاق المسار
كود :
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.ProgressBar1.Value = 0
Me.BackgroundWorker1.RunWorkerAsync()
End Sub
حيث نعيد ProgressBar إلى القيمة صفر لكى يكون فارغ
ثم نشغل المشار
المشاركات : 2,523
المواضيع 707
الإنتساب : Sep 2012
السمعة :
48
الشكر: 91
تم شكره 1104 مرات في 297 مشاركات
بالطبع اتضحت الرؤيا لك الآن أكثر وأكثر
تعال نزيد من بعض التلميحات حول الموضوع
نضع هذه الخصائص فى حدث تحميل الفورم
كود :
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.BackgroundWorker1.WorkerReportsProgress = True
Me.BackgroundWorker1.WorkerSupportsCancellation = True
Me.ProgressBar1.Minimum = 0
Me.ProgressBar1.Maximum = 100
End Sub
لقد أزدنا فى حدث التحميل أن نشطنا خاصية WorkerSupportsCancellation للعنصر
كود :
Me.BackgroundWorker1.WorkerSupportsCancellation = True
==========================================
نجعل الكود للحدث DoWork
كود :
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
For I As Integer = 0 To 100
If Me.BackgroundWorker1.CancellationPending Then
e.Cancel = True
Return
End If
Me.BackgroundWorker1.ReportProgress(I)
System.Threading.Thread.Sleep(100)
Next
End Sub
============================================
الحدث ProgressChanged كما هو
كود :
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Me.ProgressBar1.Value = e.ProgressPercentage
End Sub
================================================
جاء دور حدث جديد وهو RunWorkerCompleted ويتم فى حالة المهمة انتهت أو توقفت
كود :
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
If Not (e.Error Is Nothing) Then
MessageBox.Show("حدث خطأ")
ElseIf e.Cancelled Then
MessageBox.Show("تم الالغاء")
Else
MessageBox.Show("تمت العملية")
End If
End Sub
الكود واضح وما يحتاج شرح
=====================================
كود :
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.ProgressBar1.Value = 0
Me.BackgroundWorker1.RunWorkerAsync()
End Sub
حدث الزر Button2 الخاص بالغاء العملية
كود :
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
If Me.BackgroundWorker1.IsBusy Then
Me.BackgroundWorker1.CancelAsync()
End If
End Sub
شغل التطبيق واستمتع
المشاركات : 2,523
المواضيع 707
الإنتساب : Sep 2012
السمعة :
48
الشكر: 91
تم شكره 1104 مرات في 297 مشاركات
نقطة هامة اضافية
عندما نبدأ تشغيل المسار نكتب
كود :
Me.BackgroundWorker1.RunWorkerAsync()
لكن يمكن أن ترسل برامتر للحدث DoWork وهذا البرامتر تلقفه العنصر e الخاص بالحدث
كمثال :
كود :
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
For I As Integer = 0 To CInt(e.Argument)
If Me.BackgroundWorker1.CancellationPending Then
e.Cancel = True
Return
End If
Me.BackgroundWorker1.ReportProgress(I)
System.Threading.Thread.Sleep(100)
Next
End Sub
هنا كتبنا حلقة For من صفر حتى e.Argumen
لكن ما قيمة e.Argumen
قيمتها ترسل كبرامتر أثناء اطلاق شعلة البدء
كود :
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.ProgressBar1.Value = 0
Me.BackgroundWorker1.RunWorkerAsync(100)
End Sub
|