สำหรับเวอร์ชันภาษาอังกฤษ โปรดดู: http://dflying.dflying.net/1/archive/100_building_a_real_time_progressbar_using_aspnet_atlas.html
เมื่อมีการดำเนินการในระยะยาวในเบื้องหลัง จะเป็นความสำเร็จที่หายากมากหากสามารถระบุแถบความคืบหน้าบนหน้าเว็บเพื่อแสดงความคืบหน้าจริง แทนที่จะปล่อยให้ผู้ใช้รอโดยไม่รู้ตัวหรือประมาณการง่ายๆ ในอดีต สถานที่. ตอนนี้สามารถทำได้โดยใช้ ASP.NET Atlas แล้ว บทความนี้จะกล่าวถึงวิธีการทำให้ฟังก์ชันนี้บรรลุผลสำเร็จ และแนะนำแนวคิดพื้นฐานบางประการเกี่ยวกับการพัฒนาการควบคุมไคลเอ็นต์ Atlas คุณยังสามารถดาวน์โหลดโปรแกรมตัวอย่างและไฟล์ต้นฉบับได้ที่นี่
แนวคิดในการใช้แถบความคืบหน้าบนหน้าเว็บนั้นง่ายมาก: เขียนตัวควบคุม Atlas ฝั่งไคลเอ็นต์ ขอเซิร์ฟเวอร์เป็นครั้งคราว และใช้ข้อมูลความคืบหน้าปัจจุบันที่ส่งคืนเพื่ออัปเดตการแสดงแถบความคืบหน้า . ในตัวอย่างนี้ จะมีโค้ดสี่ส่วน:
Web Service ที่ใช้เวลานานในการดำเนินการให้เสร็จสมบูรณ์
บริการเว็บที่ใช้ในการสอบถามความคืบหน้าของบริการเว็บข้างต้น
ตัวควบคุมแถบความคืบหน้า Atlas ของไคลเอ็นต์ (ProgressBar) มีหน้าที่รับผิดชอบในการรักษาตรรกะของไคลเอ็นต์และแสดงผล UI แบบภาพ นี่เป็นองค์ประกอบที่สำคัญที่สุดในตัวอย่างนี้และสามารถนำมาใช้ซ้ำในการพัฒนาเพจหรือโปรแกรมอื่น ๆ ได้ในอนาคต หน้าทดสอบ ASP.NET ที่มีบริการเว็บและการควบคุมข้างต้นด้านล่างนี้เราใช้สี่ขั้นตอนข้างต้นทีละขั้นตอน :
ใช้เวลานาน Web Service ที่ใช้เวลานานในการดำเนินการให้เสร็จสมบูรณ์
ในโปรแกรมจริง Web Service ที่ใช้เวลานานในการดำเนินการให้เสร็จสิ้นอาจมีข้อความดังนี้
1[WebMethod]
2 โมฆะสาธารณะ TimeConsumingTask ()
3{
4 เชื่อมต่อไปยังฐานข้อมูล();
5 GetSomeValueFromDataBase();
6 คัดลอกบางไฟล์จากดิสก์();
7 GetARemoteFile();
8}
ด้วยวิธีนี้ เราสามารถแทรกวิธีการเสริมบางอย่างเพื่อกำหนดสถานะความคืบหน้าในปัจจุบันได้ setProgress(int) ใช้เพื่อตั้งค่าเปอร์เซ็นต์ความสำเร็จของความคืบหน้าในปัจจุบัน:
1[WebMethod]
2 โมฆะสาธารณะ TimeConsumingTask ()
3{
4 ชุดความคืบหน้า(0);
5ConnectToDataBase();
6 ชุดความคืบหน้า(10);
7 GetSomeValueFromDataBase();
8 ชุดความคืบหน้า (40);
9 คัดลอกบางไฟล์จากดิสก์();
10 เซ็ตความคืบหน้า(50);
11 GetARemoteFile();
12 เซ็ตความคืบหน้า(100);
13}
ในตัวอย่างนี้ เราใช้แคชเพื่อจัดเก็บข้อมูลความคืบหน้าให้เสร็จสิ้นเท่านั้น และใช้เมธอด Thread.Sleep() เพื่อจำลองความล่าช้าของการดำเนินการ:
1[WebMethod]
2 สาธารณะ int StartTimeConsumingTask ()
3{
4 สตริง processKey = this.Context.Request.UserHostAddress;
5 string threadLockKey = "thread" + this.Context.Request.UserHostAddress;
6 วัตถุ threadLock = this.Context.Cache [threadLockKey];
7 ถ้า (threadLock == null)
8 {
9 threadLock = วัตถุใหม่ ();
10 this.Context.Cache[threadLockKey] = threadLock;
11 }
12
13 // อนุญาตเพียง 1 งานที่ทำงานอยู่ต่อผู้ใช้
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 (เธรดล็อค);
28
29 กลับ (DateTime.Now - startTime).วินาที;
30}
31
Web Service สำหรับการสืบค้นความคืบหน้า
นั้นใช้งานง่าย เพียงรับข้อมูลความคืบหน้าจาก Cache:
1[WebMethod]
2public int GetProgress ()
3{
4 สตริง processKey = this.Context.Request.UserHostAddress;
ความคืบหน้าของวัตถุ 5 รายการ = this.Context.Cache[processKey];
6 ถ้า (ความคืบหน้า != null)
7 {
8 ผลตอบแทน (int) ความคืบหน้า;
9}
10
11 กลับ 0;
12}
การควบคุมแถบความคืบหน้าฝั่งไคลเอ็นต์ (ProgressBar)
ขั้นตอนที่ 1: สืบทอดจาก Sys.UI.Control
การควบคุม ProgressBar ควรสืบทอดจากคลาสฐานควบคุม Atlas Sys.UI.Control และประกาศเป็นคลาสที่ปิดผนึก (คลาสที่ปิดผนึก ซึ่งสามารถ ไม่ได้รับการสืบทอดอีกต่อไป) ) คลาสพื้นฐาน Sys.UI.Control ประกอบด้วยการดำเนินการและวิธีการบางอย่างที่ใช้ร่วมกับการควบคุมทั้งหมด ตัวอย่างเช่น การเชื่อมโยงตัวคุณเองกับองค์ประกอบ HTML (หรือที่เรียกว่าการเชื่อมโยง) เป็นต้น ในเวลาเดียวกันจะต้องลงทะเบียนเพื่อแจ้งให้ Atlas ทราบเกี่ยวกับประเภทใหม่นี้เพื่อการประกาศและการใช้งานในอนาคต เป็นต้น เพื่อให้ Atlas ได้รับคำอธิบายประเภทนี้ เป็นต้น
1Sys.UI.ProgressBar = ฟังก์ชั่น (associatedElement) {
2 Sys.UI.ProgressBar.initializeBase (นี่, [associatedElement]);
3
4}
5Type.registerSealedClass('Sys.UI.ProgressBar', Sys.UI.Control);
6Sys.TypeDescriptor.addType('script','progressBar', Sys.UI.ProgressBar);
7
ขั้นตอนที่ 2: เพิ่มสมาชิกส่วนตัวและเขียน Setter/Getter ที่เกี่ยวข้อง
ถัดไป คุณต้องเพิ่มคุณสมบัติบางอย่างเพื่อตั้งค่าการควบคุมของเรา ในตัวอย่างนี้ เราต้องการคุณสมบัติสามประการ:
Interval ช่วงเวลาระหว่างการสอบถามความคืบหน้าแต่ละครั้งและแถบความคืบหน้าได้รับการอัปเดต หน่วย: มิลลิวินาที
Service Url เส้นทางของไฟล์บริการบนเว็บ
Service Method ชื่อของวิธีการรับข้อมูลความคืบหน้า
คุณสมบัติเหล่านี้ควรเป็นไปตามหลักการตั้งชื่อของ Atlas อย่างเคร่งครัด: Getters ควรเริ่มต้นด้วย 'get_' และ Setter ควรขึ้นต้นด้วย 'set_' และส่งผ่านในพารามิเตอร์ คุณต้องเพิ่มคำอธิบายของคุณสมบัติเหล่านี้ในตัวอธิบายของตัวควบคุมด้วย วิธีการอธิบาย (descriptor) จะอธิบายไว้ในขั้นตอนที่สี่ ตัวอย่างเช่น สำหรับแอตทริบิวต์ Service Method เรามีคำสั่งต่อไปนี้:
1var _serviceMethod;
2
3this.get_serviceMethod = ฟังก์ชั่น() {
4 กลับ _serviceMethod;
5}
6
7this.set_serviceMethod = ฟังก์ชั่น (ค่า) {
8 _serviceMethod = ค่า;
9}
ขั้นตอนที่ 3: ใช้ Timer control เพื่อสอบถาม Web Service
Sys เป็นครั้งคราว Timer ใช้เพื่อเรียกเมธอด (ปล่อยเหตุการณ์) ทุกครั้ง เราสามารถกำหนดผู้รับมอบสิทธิ์ให้ชี้ไปที่เมธอดนี้และดำเนินการทุกครั้ง สืบค้นบริการบนเว็บนี้ภายในระยะเวลาหนึ่ง เพื่อหลีกเลี่ยงการรั่วไหลของหน่วยความจำเบราว์เซอร์ คุณควรอย่าลืมทำการล้างข้อมูลที่จำเป็นเมื่อส่วนควบคุมถูกทำลาย (ทิ้ง)
นอกจากนี้ โปรดทราบว่าคุณไม่ควรส่งคำขอครั้งที่สองเมื่อคำขอก่อนหน้าไม่ส่งคืน
1var _timer = Sys.Timer ใหม่ ();
2var _responsePending;
3var _tickHandler;
4var _obj = นี่;
5
6this.initialize = ฟังก์ชั่น() {
7 Sys.UI.ProgressBar.callBaseMethod (นี่คือ 'เริ่มต้น');
8 _tickHandler = Function.createDelegate(นี่, this._onTimerTick);
9 _timer.tick.add(_tickHandler);
10 นี้.set_progress(0);
11}
12
13this.dispose = ฟังก์ชั่น() {
14 ถ้า (_timer) {
15 _timer.tick.remove(_tickHandler);
16 _tickHandler = โมฆะ;
17 _timer.ทิ้ง();
18}
19 _timer = โมฆะ;
20 องค์ประกอบที่เกี่ยวข้อง = null;
21 _obj = โมฆะ;
ยี่สิบสอง
23 Sys.UI.ProgressBar.callBaseMethod (นี่คือ 'กำจัด');
ยี่สิบสี่}
25
26this._onTimerTick = ฟังก์ชั่น (ผู้ส่ง eventArgs) {
27 ถ้า (!_responsePending) {
28 _responsePending = จริง;
29
30 // เรียกวิธีการบริการแบบอะซิงโครนัส
31 Sys.Net.ServiceMethod.invoid(_serviceURL, _serviceMethod, null, null, _onMethodComplete);
32}
33}
34
35function _onMethodComplete (ผลลัพธ์) {
36 // อัปเดตแถบความคืบหน้า
37 _obj.set_progress(ผลลัพธ์);
38 _responsePending = เท็จ;
39}
ขั้นตอนที่ 4: เพิ่มวิธีการควบคุม
เราควรสามารถควบคุมการเริ่ม/หยุดของแถบความคืบหน้าได้ นอกจากนี้ สำหรับการควบคุม Atlas ยังจำเป็นต้องใช้วิธีการอธิบายที่เกี่ยวข้อง (ตัวอธิบาย) อีกด้วย Atlas จะใช้ข้อมูลนี้เพื่ออธิบายข้อมูลประเภทนี้
1this.getDescriptor = ฟังก์ชั่น() {
2 var td = Sys.UI.ProgressBar.callBaseMethod (นี่คือ 'getDescriptor');
3 td.addProperty('ช่วงเวลา', หมายเลข);
4 td.addProperty('ความคืบหน้า', หมายเลข);
5 td.addProperty('serviceURL', สตริง);
6 td.addProperty('serviceMethod', สตริง);
7 td.addMethod('เริ่มต้น');
8 td.addMethod('หยุด');
9 กลับ td;
10}
11
12this.start = ฟังก์ชั่น() {
13 _timer.set_enabled(จริง);
14}
15
16this.stop = ฟังก์ชั่น() {
17 _timer.set_enabled(เท็จ);
18}
ตกลง การควบคุมไคลเอนต์เสร็จสมบูรณ์แล้ว เราบันทึกเป็น ProgressBar.js
หน้าทดสอบ ASP.NET หน้าทดสอบ ASP.NET
สำหรับหน้า Atlas ใดๆ สิ่งแรกที่เราต้องทำคือเพิ่มการควบคุมเซิร์ฟเวอร์ ScriptManager ในตัวอย่างนี้ เราจะอ้างอิงถึงตัวควบคุม ProgressBar บริการเว็บที่ใช้เวลานานในการดำเนินการให้เสร็จสมบูรณ์ และบริการเว็บ Progress Query (บริการเว็บทั้งสองนี้อยู่ในไฟล์เดียวกัน: 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 ตระกูลฟอนต์: tahoma;
4}
5.progressBarContainer {}{
6 เส้นขอบ: 1px ทึบ #000;
7 กว้าง: 500px;
8 ความสูง: 15px;
9}
10. แถบความคืบหน้า {}{
11 สีพื้นหลัง: สีเขียว;
12 ความสูง: 15px;
13 กว้าง: 0px;
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;" value="เริ่มงานที่ใช้เวลานาน!" />
23<div id="เอาท์พุต" ></div>
สุดท้ายนี้ มี JavaScript ส่วนหนึ่งในการเริ่มบริการเว็บที่ใช้เวลานานในการดำเนินการให้เสร็จสิ้นและปล่อยให้ตัวควบคุม ProgressBar เริ่มทำงาน:
ภาพหน้าจอและดาวน์โหลด
ตอนนี้ทุกอย่างเสร็จแล้วและพร้อมที่จะรัน!
การเริ่มต้นหน้า:
วิ่ง:
วิ่งเสร็จแล้ว: