للحصول على النسخة الإنجليزية، راجع: http://dflying.dflying.net/1/archive/100_building_a_real_time_progressbar_using_aspnet_atlas.html
عندما يتم تنفيذ بعض العمليات طويلة المدى في الخلفية، سيكون إنجازًا نادرًا جدًا إذا أمكن توفير شريط تقدم على الصفحة لإظهار التقدم الحقيقي، بدلاً من السماح للمستخدمين بالانتظار دون علم أو إجراء تقديرات بسيطة في الماضي. مكان. أصبح الآن من الممكن تمامًا القيام بذلك باستخدام ASP.NET Atlas. ستناقش هذه المقالة كيفية إنجاز هذه الوظيفة وتقديم بعض المفاهيم الأساسية حول تطوير التحكم في عميل Atlas. يمكنك أيضًا تنزيل نماذج البرامج والملفات المصدرية هنا.
إن فكرة تنفيذ شريط التقدم على صفحة الويب هي في الواقع بسيطة للغاية: اكتب عنصر تحكم Atlas من جانب العميل، واطلب من الخادم بين الحين والآخر، واستخدم بيانات التقدم الحالية التي تم إرجاعها لتحديث عرض شريط التقدم . في هذا المثال، سيكون هناك أربعة أجزاء من التعليمات البرمجية:
خدمة ويب تستغرق وقتًا طويلاً لإكمالها
خدمة ويب تُستخدم للاستعلام عن مدى تقدم خدمة الويب المذكورة أعلاه
يعد عنصر تحكم شريط التقدم (ProgressBar) الخاص بالعميل Atlas مسؤولاً عن الحفاظ على منطق العميل وإخراج واجهة المستخدم المرئية. يعد هذا أيضًا العنصر الأكثر أهمية في هذا المثال ويمكن إعادة استخدامه في تطوير صفحات أو برامج أخرى في المستقبل. صفحة اختبار ASP.NET تحتوي على خدمة الويب وعناصر التحكم المذكورة أعلاه، وفيما يلي نقوم بتنفيذ الخطوات الأربع المذكورة أعلاه خطوة بخطوة :
تستغرق خدمة الويب وقتًا طويلاً وتستغرق وقتًا طويلاً لإكمالها
في برنامج فعلي، قد تحتوي خدمة الويب التي تستغرق وقتًا طويلاً لإكمالها على العبارة التالية:
1[WebMethod]
2 الفراغ العام TimeConsumingTask ()
3 {
4 ConnectToDataBase();
5 GetSomeValueFromDataBase();
6 CopySomeFilesFromDisk();
7 GetARemoteFile();
8}
بهذه الطريقة، يمكننا إدراج بعض الطرق المساعدة لتحديد حالة إكمال التقدم الحالية. يتم استخدام setProgress(int) لتعيين النسبة المئوية لاكتمال التقدم الحالي:
1[WebMethod]
2 الفراغ العام TimeConsumingTask ()
3 {
4 setProgress(0);
5ConnectToDataBase();
6 setProgress(10);
7 GetSomeValueFromDataBase();
8 setProgress(40);
9 CopySomeFilesFromDisk();
10 setProgress(50);
11 GetARemoteFile();
12 setProgress(100);
13}
في هذا المثال، نستخدم ذاكرة التخزين المؤقت فقط لتخزين معلومات إكمال التقدم ونستخدم طريقة Thread.Sleep() لمحاكاة تأخير العملية:
1[WebMethod]
2 كثافة العمليات العامة StartTimeConsumingTask()
3 {
4 سلسلة ProcessKey = this.Context.Request.UserHostAddress;
5 سلسلة threadLockKey = "thread" + this.Context.Request.UserHostAddress;
6 كائن threadLock = this.Context.Cache[threadLockKey];
7 إذا (threadLock == فارغ)
8 {
9 threadLock = كائن جديد ()؛
10 this.Context.Cache[threadLockKey] = threadLock;
11 }
12
13 // السماح فقط بمهمة واحدة قيد التشغيل لكل مستخدم.
14 إذا (!Monitor.TryEnter(threadLock, 0))
15 عودة -1؛
16
17 DateTime startTime = DateTime.Now;
18
19 // محاكاة مهمة تستغرق وقتا طويلا.
20 لـ (int i = 1؛ i <= 100؛ i++)
واحد وعشرون {
22 // تحديث التقدم لهذه المهمة.
23 this.Context.Cache[processKey] = i;
24 خيط.النوم(70);
25}
26
27 Monitor.Exit(threadLock);
28
29 إرجاع (DateTime.Now - startTime).Seconds;
30}
31
من السهل تنفيذ
خدمة الويب للاستعلام عن التقدم
، ما عليك سوى الحصول على معلومات التقدم من ذاكرة التخزين المؤقت:1[WebMethod]
2public int GetProgress()
3 {
4 سلسلة ProcessKey = this.Context.Request.UserHostAddress;
5 تقدم الكائن = this.Context.Cache[processKey];
6 إذا (التقدم! = فارغ)
7 {
8 عودة (كثافة العمليات) التقدم؛
9}
10
11 العودة 0؛
12}
التحكم في شريط التقدم من جانب العميل (ProgressBar)
الخطوة 1: وراثة من Sys.UI.Control
يجب أن يرث عنصر التحكم ProgressBar من فئة التحكم الأساسية في Atlas Sys.UI.Control والإعلان عنها كفئة مختومة (فئة مختومة، والتي يمكن لم تعد موروثة)). تحتوي الفئة الأساسية Sys.UI.Control على بعض العمليات والأساليب الشائعة لجميع عناصر التحكم. على سبيل المثال، ربط نفسك بعنصر HTML (المعروف أيضًا باسم الربط)، وما إلى ذلك. وفي نفس الوقت يجب التسجيل لإعلام أطلس بهذا النوع الجديد للإعلان عنه واستخدامه في المستقبل، على سبيل المثال، حتى يتمكن أطلس من الحصول على وصف هذا النوع وما إلى ذلك.
1Sys.UI.ProgressBar = وظيفة(associatedElement) {
2 Sys.UI.ProgressBar.initializeBase(this, [associatedElement]);
3
4}
5Type.registerSealedClass('Sys.UI.ProgressBar', Sys.UI.Control);
6Sys.TypeDescriptor.addType('script','progressBar', Sys.UI.ProgressBar);
7
الخطوة 2: إضافة أعضاء خاصين وكتابة Setter/Getter المطابقين
بعد ذلك، تحتاج إلى إضافة بعض الخصائص لتعيين التحكم الخاص بنا. في هذا المثال، نحتاج إلى ثلاث خصائص:
الفاصل الزمني بين كل مرة يتم فيها إعادة الاستعلام عن التقدم وتحديث شريط التقدم. الوحدة: ميلي ثانية
عنوان URL للخدمة. مسار ملف خدمة الويب.
طريقة الخدمة اسم الطريقة للحصول على معلومات التقدم.
يجب أن تتبع هذه الخصائص اصطلاح التسمية الخاص بـ Atlas بدقة: يجب أن يبدأ Getters بـ "get_"، ويجب أن يبدأ Setter بـ "set_" وتمرير المعلمة. تحتاج أيضًا إلى إضافة أوصاف هذه الخصائص في واصف عنصر التحكم. سيتم شرح طريقة الوصف (الواصف) في الخطوة الرابعة. على سبيل المثال، بالنسبة لسمة أسلوب الخدمة، لدينا العبارة التالية:
1var _serviceMethod;
2
3this.get_serviceMethod = function() {
4 طريقة خدمة الإرجاع؛
5}
6
7this.set_serviceMethod = الوظيفة(القيمة) {
8_serviceMethod = value;
9}
الخطوة 3: استخدم عنصر التحكم Timer للاستعلام عن Web Service
Sys بين الحين والآخر. يتم استخدام Timer لاستدعاء طريقة (إصدار حدث) في كل مرة. يمكننا تحديد مفوض للإشارة إلى هذه الطريقة والقيام بذلك في كل مرة الاستعلام عن خدمة الويب هذه خلال فترة زمنية. لتجنب تسرب ذاكرة المتصفح، يجب أن تتذكر القيام ببعض عمليات التنظيف الضرورية عند إتلاف عنصر التحكم (التخلص منه).
لاحظ أيضًا أنه لا ينبغي عليك إرسال طلب ثانٍ في حالة عدم إرجاع الطلب السابق.
1var _timer = new Sys.Timer();
2var _responsePending;
3var _tickHandler;
4var _obj = هذا؛
5
6this.initialize = function() {
7 Sys.UI.ProgressBar.callBaseMethod(this, 'initialize');
8 _tickHandler = Function.createDelegate(this, this._onTimerTick);
9 _timer.tick.add(_tickHandler);
10 this.set_progress(0);
11}
12
13this.dispose = الدالة() {
14 إذا (_المؤقت) {
15 _timer.tick.remove(_tickHandler);
16 _tickHandler = null;
17 _timer.dispose();
18}
19 _timer = null;
20 AssociateElement = null;
21 _obj = null;
إثنان وعشرون
23 Sys.UI.ProgressBar.callBaseMethod(this, 'dispose');
أربعة وعشرون }
25
26this._onTimerTick = function(sender, eventsArgs) {
27 إذا (!_responsePending) {
28 _responsePending = صحيح؛
29
30 // استدعاء طريقة الخدمة بشكل غير متزامن.
31 Sys.Net.ServiceMethod.invoc(_serviceURL, _serviceMethod, null, null, _onMethodComplete);
32}
33}
34
35وظيفة _onMethodComplete(result) {
36 // تحديث شريط التقدم.
37 _obj.set_progress(result);
38 _responsePending = خطأ;
39}
الخطوة 4: إضافة طريقة تحكم
يجب أن نكون قادرين على التحكم في بدء/إيقاف شريط التقدم. علاوة على ذلك، بالنسبة لعنصر تحكم أطلس، فإن طريقة الوصف ذات الصلة (الواصف) ضرورية أيضًا. سوف يستخدمه Atlas لوصف هذا النوع من المعلومات.
1this.getDescriptor = function() {
2 var td = Sys.UI.ProgressBar.callBaseMethod(this, 'getDescriptor');
3 td.addProperty('interval', Number);
4 td.addProperty('progress', Number);
5 td.addProperty('serviceURL', String);
6 td.addProperty('serviceMethod', String);
7 td.addMethod('start');
8 td.addMethod('stop');
9 عودة الدفتيريا.
10}
11
12this.start = الدالة() {
13 _timer.set_enabled(true);
14}
15
16this.stop = الدالة() {
17 _timer.set_enabled(false);
18}
حسنًا، تم الانتهاء من التحكم في العميل حتى الآن. نقوم بحفظه باسم ProgressBar.js.
صفحة اختبار ASP.NET صفحة اختبار ASP.NET
بالنسبة لأي صفحة Atlas، أول شيء يتعين علينا القيام به هو إضافة عنصر تحكم خادم ScriptManager. في هذا المثال، سنشير إلى عنصر التحكم ProgressBar، وخدمة الويب التي تستغرق وقتًا طويلاً لإكمالها، وخدمة الويب للاستعلام عن التقدم. (توجد خدمتا الويب هاتان في نفس الملف: TaskService.asmx)
1<atlas:ScriptManager ID="ScriptManager1" runat="server" >
2 <مخطوطات>
3 <atlas:ScriptReference Path = "ScriptLibrary/ProgressBar.js" ScriptName = "مخصص" />
4 </مخطوطات>
5 <الخدمات>
6 <atlas:ServiceReference Path="TaskService.asmx" />
7 </الخدمات>
8</atlas:ScriptManager>
التالي هو تخطيط الصفحة ونمطها:
1<style type="text/css">
2* {}{
3 عائلة الخطوط: تاهوما؛
4}
5.progressBarContainer {}{
6 الحدود: 1px الصلبة #000؛
7 العرض: 500 بكسل؛
8 الارتفاع: 15 بكسل؛
9}
10. شريط التقدم {}{
11 لون الخلفية: أخضر؛
12 ارتفاع: 15 بكسل؛
13 العرض: 0 بكسل؛
14 حجم الخط: غامق؛
15}
16</نمط>
17
18<div>تقدم المهمة</div>
19<div class="progressBarContainer">
20 <div id="pb" class="progressBar"></div>
21</div>
22<input type = "button" id = "start" onclick = "startTask ()؛ return false؛" = "ابدأ المهمة المستهلكة للوقت!"
23<div id="output" </div>
أخيرًا، هناك جزء من JavaScript لبدء خدمة الويب يستغرق وقتًا طويلاً لإكماله والسماح لعنصر التحكم ProgressBar ببدء العمل:
لقطات الشاشة والتنزيلات
الآن تم الانتهاء من كل شيء وجاهز للتشغيل!
تهيئة الصفحة:
جري:
اكتمل التشغيل: