Basic:
Private Sub LengthyProcedure()
'
' الاجراء التالي يفترض انه اجراء التحميل الطويل والذي
' يفترض ان يستغرق وقت لانهائه
' وقد وضعت 3 ثواني كمثال
'
Threading.Thread.Sleep(3000)
MessageBox.Show("تم الانتهاء من اجراء التحميل الطويل.")
End Sub
C#:
private void LengthyProcedure ()
{
//
// الاجراء التالي يفترض انه اجراء التحميل الطويل والذي
// يفترض ان يستغرق وقت لانهائه
// وقد وضعت 3 ثواني كمثال
//
System.Threading.Thread.Sleep(3000);
MessageBox.Show("تم الانتهاء من اجراء التحميل الطويل.");
}
وتحتاج الى استدعائه لحظة تحميل البرنامج، فقد تكتب في حدث Load عملية الاستدعاء بشكل مباشر:
Basic:
Private Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.LengthyProcedure()
End Sub
C#:
private void Form_Load(object sender, EventArgs e)
{
this.LengthyProcedure();
}
الخطوة السابقة ستؤدي الى شلل كامل للبرنامج وعلى المستخدم الانتظار حتى ينتهي تنفيذ الاجراء ومن بعدها ستظهر النافذة، ويبقى الحل الأفضل هو تنفيذ الاجراء في مسار تنفيذي Thread مستقل:
Basic:
Private Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
With New Threading.Thread(AddressOf Me.LengthyProcedure)
.Start()
End With
End Sub
C#:
private void Form_Load(object sender, EventArgs e)
{
new System.Threading.Thread(new
System.Threading.ThreadStart(this.LengthyProcedure)).Start();
}
في المثال السابق، ستظهر النافذة وسيتم تنفيذ الاجراء الطويل في مسار تنفيذي Thread مستقل دون أن يحس به المستخدم، وقد تعارض الفكرة وتقول أن البرنامج ليس جاهز (بشكل كامل) حتى يتم تحميل كافة متطلباته، كلامك صحيح من ناحية نظرية ولكن في الفترة التي ستظهر فيها النافذة ويبدأ المستخدم بتحريك يده الى لوحة المفاتيح او مسك الفأرة والوقت الذي سيستغرقه المستخدم في التفكير لتنفيذ وظيفة معينة في واجهة الاستخدام او تحريك النافذة لوضعها في مكان مناسب للعمل عليها (كتكبيرها مثلا)، ستكون فترة كافية (قد تتعدى 5 ثواني) لتنفيذ الاجراء الطويل LengthyProcedure().
على هذا الرابط تجد مثال للحالتين:
أما ان لم تكن معارض لهذه الفكرة وكن مؤيد لها، فستصاب بخيبة أمل كبيرة إن علمت ان من احد ابرز عيوب مسارات التنفيذ مع تطبيقات Windows Application أنها ((لا)) تسمح لك بكتابة أي شيفرة تحتك مع النافذة او الادوات الا ان كان الشيفرة مستدعاة من قبل ((نفس)) مسار التنفيذ الذي أنشأ النافذة، فلو كتبت شيئا مثل:
Basic:
Private Sub LengthyProcedure()
...
...
Me.Button1.Text = "تم الانتهاء من اجراء التحميل الطويل."
End Sub
C#:
private void LengthyProcedure ()
{
...
...
this.Button1.Text = "تم الانتهاء من اجراء التحميل الطويل.";
}
سينفجر استثناء من النوع InvalidOperationException حاملا رسالة "Cross-thread operation not valid: Control 'Button1' accessed from a thread other than the thread it was created on." مفادها ان الاداة التي تصل اليها تم من خلال مسار تنفيذ غير المسار التنفيذي الذي أنشأ النافذة، فحاول التعامل مع اجزاء من برنامجك ليس لها علاقة بواجهة الاستخدام.
مع ذلك، يمكنك الالتفاف حول هذا القصور (الوصول الى ادوات Windows Forms من مسارات تنفيذ مختلفة Different threads ولكنها بحاجة الى قليل من التفصيل والتطريز (سأكتب عنها قريبا بإذن الله).
أخيرا، صدقني بداية تشغيل البرنامج هي السبب الرئيسي في تحديد الانطباع الايجابي او السلبي في نظر المستخدم حتى لو كانت باقي وظائف البرنامج (بعد تشغيله) بطيئة! تماما كما ترى أي شخص لأول مرة، فإن انطباعك الأولي عنه يظل فترة طويلة حتى يتغير مع معاشرته.
-- تركي