• 1
عبد العظيم بخاري

التهيئة المتأخرة عن طريق كلاس Lazy (جديد دوت نت 4)

سؤال

يقدم لنا اطار عمل الدوت نت 4 كلاس جديد اسمه Lazy<T> والذي يعمل على تهيئة الأنواع والكائنات بشكل متأخر .

لكن ماذا نعني بالتهيئة المتأخرة ؟

تخيل عزيزي القارئ أنه يوجد عندك صفحة سلفرلايت على سبيل المثال تحتوي على 40 يوزر كنترول موضوعين في array , لكنك فعلياً تعرض ثلاثة منهم فقط للمستخدم مع الحاجة لتهيئة جميع الcontrols الموجودين في الarray حتى يتم عرضهم في وقت لاحق حين يطلبهم المستخدم على سبيل المثال.

لذلك عند تحميل الصفحة سيتم حجز مكان ل40 يوزر كنترول في الذاكرة مع العلم أن 37 منهم لا لزوم لهم (على الأقل في الوقت الراهن) مما يجعل المنطقة المستخدمة من الذاكرة لهذه الصفحة اكبر من الحاجة.

يمكننا باستعمال التهيئة المتأخرة عن طريق كلاس Lazy<T> توفير هذه الكمية الكبيرة من الذاكرة بحيث أن كل كنترول يتم تهيئه عن الوصول الأول له , بمعنى أن حجز الكنترول لمنطقة معينة في الذاكرة يتم عند طلب هذا الكنترول فقط.

تخيل كمية التوفير في الresources عند استعمالنا لهذا الكلاس !!

كيفية عمل تهيئة متأخرة

سنأخذ مثال اخر اكثر شيوعاً .. فلنفترض أنه يوجد لدينا List من الموظفين يحتوي كل عنصر منها على اسم الموظف وصورته (التي يحضرها من مجلد خارجي) وكان عندنا هذا الكلاس الذي يمثل كل الموظف :

class Employee {
public string EmployeeName { get; set; }
public Stream EmployeePicture { get; set; }

public Employee(string employeeName, Stream employeePicture) {
EmployeeName = employeeName;
EmployeePicture = employeePicture;
}

}

فلو كان النظام الذي لدينا يستعمل صور الموظفين في حالات نادرة فستكون التهيئة المتأخرة ممتازة جداً لبرنامجنا . والسبب هو أن نوع صورة يتعامل مع unmanaged resources والتي تحتاج لحجز منطقة كبيرة جداً في الذاكرة عند تهيئتها وبالتالي يصبح عندنا استهلاك رهيب للذاكرة دون الحاجة لهذا كله.

سيكون برنامجنا رائع ومميز في حال تم تهيئة صورة الموظف عند الحاجة لها فقط وهذا ما سنقوم به باستخدام التهيئة المتأخرة عن طريق كلاس Lazy<T> .

سيصبح عندنا شكل الكلاس كالاتي:

class Employee {
Lazy<Stream> _employeePicture;
public string EmployeeName { get; set; }
public Stream EmployeePicture{
get { return _employeePicture.Value; }
set { _employeePicture = new Lazy<Stream>(() => value, true); }
}

public Stream EmployeePicture { get; set; }

public Employee(string employeeName, Stream employeePicture) {
EmployeeName = employeeName;
_employeePicture = new Lazy<Stream>(() => EmployeePictureFactory.GetPictureFromDisk(fileName), true);
}

}
static class EmployeePictureFactory {
public static Stream GetPictureFromDisk(string fileName) {
if (string.IsNullOrEmpty(fileName))
fileName = @"C:\photos\sample.jpg";
return new FileStream(fileName, FileMode.Open, FileAccess.Read);
}
}

لاحظ أننا قمنا بوضع نوع الproperty التي تتعلق بصورة الموظف بLazy<Stream> والذي يقوم بتهيئة الصورة عند طلبها لاول مرة . لاحظ ايضاً اننا قمنا بوضع قيمة true للبارميتر isThreadSafe وهذا يفيد في عمل تطبيق للmulti-threaded حيث أن كلاس Lazy<T> قابل للعمل مع البرمجة المتوازية (تم شرح هذا الأمر بالتفصيل في كتاب البرمجة المتوازية في اطار عمل .NET 4 الذي ساصدره قريباً ان شاء الله ).

اما باراميتر fileName فهو من اجل رابط ملف الصورة التي نريد تحميلها لهذا الموظف , وفي حال لم يتم تحميل صورة فسنقوم بوضع صورة افتراضية من عندنا C:\photos\sample.jpg .

يمكننا الان الاطمئنان إلى أنه لن يتم حجز ذاكرة لصورة الموظف إلا في حال تم استعمال قيمة الصورة حينها سيتم عمل تهيئة ولمرة واحدة فقط.

كلاس Lazy<T>

يحتوي هذا الكلاس على عدة methods و constructors سنقوم بذكر اهمها :

- IsValueCreated هي property من نوع Boolean ترجع معلومات عن النوع T اذا ما تم عمل instance له أم لا.

- Value هي property تهيئ النوع T عند الوصول الأول له وترجع instance .

- ctor(valueFactory Func<T>): وهي ميثود ترجع instance جديد من كلاس Lazy<T> وعندما تحصل التهيئة المتأخرة يتم استعمال هذه الميثود للتهيئة .

- ctor(valueFactory Func<T>, isThreadSafe bool) : نفس الميثود السابقة إلا انه يوجد اختيار لوضعية التهيئة لدعم البرمجة المتوازية .

للحصول على معلومات اكثر عن هذا الكلاس يمكنك مراجعة الرابط التالي :

http://msdn.microsoft.com/en-us/library/dd642326(VS.100).aspx

عبد العظيم بخاري

http://www.el-bukhari.com/2010/11/lazy-4.html

3

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

1 إجابات على هذا السؤال .

  • 0

بسم الله الرحمن الرحيم

رائع

لقد وفيت وكفيت وبارك الله فيك

كنت ابحث هذا منذ فترة

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .