التنبيهات التالية ظهرت :
Warning [2] count(): Parameter must be an array or an object that implements Countable - Line: 864 - File: showthread.php PHP 7.4.33 (Linux)
File Line Function
/showthread.php 864 errorHandler->error



تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
نظرة عامة حول Event-based Asynchronous Pattern
#1
كاتب الموضوع : Islam Ibrahim

التطبيقات التي تقوم بتنفيذ عمليات متعددة في نفس الوقت تحتاج بطبيعة الحال لأن تبقى طوال الوقت مستجيبة ومستعدة لمعالجة العمليات التي يقوم بها المستخدم, يتطلب هذا الأمر عادة استخدام تعدد المسارات Multithreading , ومن أجل هذا تم تضمين مجالي الأسماء System.Threading و System.ComponentModel بمجموعة من الأدوات المناسبة لإنشاء التطبيقات متعددة المسارات ذات الأداء القوي, ولكن من أجل استخدام تلك الأدوات لا بد من أن يكون لديك دراية وخبرة كافية لتصميم تطبيق يعتمد على تعدد المسارات, وأحيانًا استخدام أداة في غير مكانها يتسبب في نتائج جانبية غير محمودة, ومن أجل ذلك يكون المكوّن BackgroundWorker هو الحل الأمثل في أغلب الأحيان, وهناك أحيان أخرى عند الحاجة لتنفيذ المهام بشكل غير متزامن تحتاج لبناء فئتك الخاصة وفقًا لنمط يُعرف بـ Event-based Asynchronous Pattern أو نمط العمليات الغير متزامنة والتي تعتمد على إطلاق الأحداث Events.

استخدام نمط العمليات الغير متزامنة بالاعتماد على الأحداث, يقدم لنا تلك المزايا التي تتمتع بها التطبيقات متعددة المسارات, في حين يخفي في طياته الكثير من التعقيدات التي يمكن أن تنشأ عند القيام ببناء التطبيقات المتعددة المسارات, وعندما تقوم ببناء فئتك الخاصة بالاعتماد على هذا النمط, سيصبح بإمكانك:
  • تنفيذ العمليات التي تستهلك وقتاً أطول أكثر من غيرها (مثل العمليات على قواعد البيانات, أو عمليات التحميل Downloading) في الخلفية بدون مقاطعة واجهة الاستخدام.
  • تنفيذ عمليات متعددة في نفس الوقت, واستقبال تنبيهات عند انتهاء كل عملية
  • الانتظار من أجل الحصول على مورد معيّن دون تعليق التطبيق وجعله عديم الاستجابة.
  • التخاطب مع العمليات الغير متزامنة أثناء تنفيذها بالاستعانة بالأحداث والمفوضات Events & Delegates.
عادة ما تحتوي الفئات التي تطبق هذا النمط على إجراء أو عدة إجراءات أسماؤهم بالشكل التالي: MethodNameAsync , يمكن أن تحتوي تلك الفئات أيضًا على أحداث أسماؤها من الشكل MethodNameCompleted ويمكن أن تحتوي أيضًا على إجراء باسم MethodNameCancelAsync أو ببساطة CancelAsync .

أداة التحكم PictureBox تعتبر مثالاً جيدًا لفئة تطبّق نمط العمليات الغير المتزامنة بالاعتماد على الأحداث , فيمكنك مثلاً تحميل صورة من موقع ما بشكل متزامن synchronously باستخدام الإجراء Load ولكن إذا كان حجم الصورة كبيرًا أو الاتصال بالإنترنت ضعيفًا فإن ذلك سيتسبب في توقف التطبيق عن الاستجابة Hanging حتى ينتهي تنفيذ الإجراء Load. وإذا أردت أن يحافظ التطبيق على استجابته ستحتاج عندها لاستخدام الإجراء LoadAsync , وهنا سيصبح بإمكانك معالجة الحدث LoadCompleted للأداة PictureBox تماماً كما تفعل مع أي حدث آخر, عندما تستدعي الإجراء LoadAsync فإن التطبيق يستمر في العمل والاستجابة وسيتم تنفيذ العملية في الخلفية في مسار مستقل عن المسار الأساسي لواجهة الاستخدام UI Thread , وسيتم استدعاء معالج الحدث LoadCompleted عند انتهاء العملية عندها يمكنك اختبار الوسيط من النوع AsyncCompletedEventArgs والذي سُيمرر لمعالج الحدث LoadCompleted للتحقق من نجاح عملية التحميل أم لا.

يتطلب نمط العمليات الغير المتزامنة هذا أن يكون هناك إمكانية لتعطيل العملية التي يتم تنفيذها بشكل غير متزامن , والأداة PictureBox بالفعل تحقق هذا المتطلب, حيث أنها تحتوي على الإجراء CancelAsync , عند استدعاء الإجراء CancelAsync سيتم إرسال طلب لإيقاف عملية التحميل التي يتم تنفيذها حالياً , وعند إيقاف العملية سيتم عندها إطلاق الحدث LoadCompleted.

مميزات هذا النمط أو لنموذج

هذا النمط أخذ عدة أشكال استنادًا إلى درجة تعقيد السيناريو الذي تنفذه كل فئة, أبسط فئة قد تحتوي على إجراء وحيد MethodNameAsync وحدث موافق لها MethodNameCompleted , الفئات الأكثر تعقيدًا قد تحتوي على أكثر من إجراء غير متزامن كل إجراء يمتلك الحدث الموافق له , يمكن أيضا أن يكون له في المقابل إجراء MethodName يتم تنفيذه بشكل متزامن.يمكن لهذه الفئات أيضًا أن تدعم إلغاء تنفيذ العملية الحالية Cancellation , تقرير حالة التقدم Report Progressing والنتائج المتراكمة عن كل عملية غير متزامنة.

إجراء غير متزامن يمكن أيضًا أن يدعم استدعاءات متتالية ومتداخلة بحيث لا يتم تنفيذ الاستدعاء الثاني للإجراء حتى ينتهي الاستدعاء الأول , وبهذه الحال يستطيع كودك استدعاء الإجراء أكثر من مرة قبل أن ينتهي من العملية الحالية . ولتنفيذ هذه الميزة قد يحتاج تطبيقك إلى تتبع تنفيذ كل عملية حتى تنتهي.

أمثلة:

تعتبر الفئتان PictureBox و SoundPlayer أبسط تمثيل لهذا النمط, بينما تمثيل الفئتان BackgroundWorker و WebClient لهذا النمط يعتبر أكثر تعقيدًا من سابقتيهما , المثال التالي يعتبر تجريد لفئة وهمية تنفذ هذا النمط:

VB Code

كود :
Public Class AsyncExample
' Synchronous methods.
Public Function Method1(ByVal param As String) As Integer
Public Sub Method2(ByVal param As Double)

' Asynchronous methods.
Overloads Public Sub Method1Async(ByVal param As String)
Overloads Public Sub Method1Async(ByVal param As String, ByVal userState As Object)
Public Event Method1Completed As Method1CompletedEventHandler

Overloads Public Sub Method2Async(ByVal param As Double)
Overloads Public Sub Method2Async(ByVal param As Double, ByVal userState As Object)
Public Event Method2Completed As Method2CompletedEventHandler

Public Sub CancelAsync(ByVal userState As Object)

Public ReadOnly Property IsBusy () As Boolean

' Class implementation not shown.
End Class
C# Code


كود :
public class AsyncExample
{
// Synchronous methods.
public int Method1(string param);
public void Method2(double param);

// Asynchronous methods.
public void Method1Async(string param);
public void Method1Async(string param, object userState);
public event Method1CompletedEventHandler Method1Completed;

public void Method2Async(double param);
public void Method2Async(double param, object userState);
public event Method2CompletedEventHandler Method2Completed;

public void CancelAsync(object userState);

public bool IsBusy { get; }

// Class implementation not shown.
}
هذه الفئة تحتوي على إجراءين كلاهما يدعم التنفيذ المتزامن والغير متزامن , الإجراءات المتزامنة كأي إجراءات أخرى سيتم تنفيذها على نفس المسار للكود الذي قام باستدعائها مما يعني أنا إذا كان هذا الإجراء يستغرق وقتًا للتنفيذ فإنه سيكون هناك تأخر في الاستجابة قبل إرجاع النتائج, بينما الإجراءات الغير متزامنة ستبدأ العمل في مسار مستقل وبذلك تسمح لمسار الكود الذي قام باستدعائها بمتابعة العمل بينما يتم تنفيذ هذا الإجراء في الخلفية.

إعادة تحميل الإجراءات الغير متزامنة Overloading

عادة هناك نسختان من كل إجراء غير متزامن نسخة يتم استدعاؤها مرة واحدة فقط, ونسخة أخرى يمكن استدعاؤها أكثر من مرة (استدعاء متعدد) تمتلك معامل زائد userState هذه النسخة كما ذكرنا سابقًا تجعل من الممكن استدعاء الإجراء أكثر من مرة دون انتظار انتهاء الإجراء من القيام بالعملية الحالية, هذه النسخة يتم استدعاؤها بالشكل التالي:

كود :
Method1Async(string param, object userState)
أما النسخة الأولى والتي لا يمكن استدعاؤها مرة أخرى قبل انتهائها من العملية الحالية فإنه عند محاولة استدعائها قبل انتهائها سيتم إطلاق الاستثناء InvalidOperationException , ويكون استدعاؤها بالشكل التالي:

كود :
Method1Async(string param)
الوسيط userState في النسخة التي تقبل استدعائها أكثر من مرة , تمكنك من تحديد الاستدعاء للإجراء من خلال توفير قيمة فريدة GUID أو مفتاح مختلط HashCode , وعند انتهاء تنفيذ العملية يمكن للحدث MethodNameCompleted تحديد أي استدعاء تم الانتهاء منه.

تتبع العمليات التي في الانتظار.

إذا كنت تستخدم إجراء غير متزامن يعتمد على الاستدعاء المتعدد فإنك تحتاج إلى تتبع كل استدعاء بحيث كل استدعاء يتميز عن غيره بقيمة فريدة TaskID كما ذكرنا سابقًا إما GUID أو HashCode عند كل استدعاء للإجراء عليك القيام بتوليد تلك القيمة وإضافتها إلى HashTable حيث كل استدعاء يقابله ال userState الخاص به, عند انتهاء الاستدعاء الحالي يتم حذف ال userState والاستدعاء الخاص به من ال HashTable.

يمكنك الإطلاع على المثال التالي من MSDN لتتضح لك الصورة أكثر.
http://msdn.microsoft.com/en-us/library/9hk12d4y.aspx

وقريبًا جدًا سأضع مثال آخر يطبق نفس ال Pattern.

بالتوفيق
}}}
تم الشكر بواسطة:


الردود في هذا الموضوع
نظرة عامة حول Event-based Asynchronous Pattern - بواسطة Raggi Tech - 08-10-12, 05:42 PM

المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  نظرة سريعة في الجديد في Visual Studio 2008 فيما يتعلق ببيئة التطوير RaggiTech 0 1,878 08-10-12, 05:45 PM
آخر رد: RaggiTech
  نظرة على جديد الفيجوال بيسك 9 - الجزء الأول RaggiTech 0 2,091 08-10-12, 05:38 PM
آخر رد: RaggiTech

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم