الحدث Load قد يرفع ضغط المستخدم

الناقل : elmasry | الكاتب الأصلى : تركي العسيري | المصدر : www.al-asiri.com

الحدث Load Event يعتبر ابرز حدث مقترن مع نافذة النموذج Form، ولا يكاد يخلو اي تطبيق Windows Forms (حقيقي) الا وتم استغلال حدث التحميل Load في نوافذه، ويكفي أنه اول حدث (الحدث الافتراضي) الذي يظهر عند الضغط المزدوج على نافذة النموذج وقت التصميم، ولكن عندما تكثر الشيفرات بين فكي هذا الحدث فهناك مشكلة يتجاهلها الكثير من المبرمجين.

فمن احد ابرز عيوب عملية تشغيل تطبيقات من نوع Windows Forms هو البطء الشديد عند تحميلها، وقد تقول أنها لا تستغرق سوى ثواني معدودات وعلى المستخدم الصبر حتى ينتهي البرنامج من تحميله، ولكن لو وضعت نفسك مكان المستخدم فهذه الثواني (القليلة في نظرك) كافية الى حد كبير لتجعله يأخذ انطباع سلبي جدا عن برنامجك ويقول بكل سهولة وتحطيم لك: برنامجك بطيء ولا يستاهل!! وأخبرني بصراحة، ماهو شعورك عندما تقوم بتشغيل برنامج يستغرق وقت طويييييييييل في تحميله؟

فلو كان لديك إجراء تنفيذه يستهلك وقت طويل (لنقل 3 ثواني على سبيل المثال):


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 ولكنها بحاجة الى قليل من التفصيل والتطريز (سأكتب عنها قريبا بإذن الله).


أخيرا، صدقني بداية تشغيل البرنامج هي السبب الرئيسي في تحديد الانطباع الايجابي او السلبي في نظر المستخدم حتى لو كانت باقي وظائف البرنامج (بعد تشغيله) بطيئة! تماما كما ترى أي شخص لأول مرة، فإن انطباعك الأولي عنه يظل فترة طويلة حتى يتغير مع معاشرته.


-- تركي