英語版については、 http ://dflying.dflying.net/1/archive/100_building_a_real_time_progressbar_using_aspnet_atlas.html を参照してください。
長期的な操作がバックグラウンドで実行されている場合、これまでのようにユーザーが知らずに待たされたり単純な見積もりをしたりするのではなく、ページ上に進行状況バーを表示して実際の進行状況を表示できれば、これは非常にまれな成果となるでしょう。場所。 ASP.NET Atlas を使用してこれを行うことが完全に可能になりました。この記事では、この機能を実現する方法について説明し、Atlas クライアント コントロール開発に関するいくつかの基本概念を紹介します。サンプルプログラムやソースファイルもここからダウンロードできます。
Web ページに進行状況バーを実装するというアイデアは、実際には非常に簡単です。クライアント側の Atlas コントロールを作成し、時々サーバーにリクエストし、返された現在の進行状況データを使用して進行状況バーの表示を更新します。 。この例では、コードは 4 つの部分で構成されます。
完了までに長い時間がかかる Web サービス
上記の Web サービスの進行状況をクエリするために使用される Web サービス
クライアント Atlas プログレス バー (ProgressBar) コントロールは、クライアント ロジックの維持とビジュアル UI の出力を担当します。これは、この例の最も重要なコンポーネントでもあり、将来他のページやプログラムの開発で再利用できます。上記の Web サービスとコントロールを含む ASP.NET テスト ページを以下に示します。 :
時間がかかります 完了までに時間がかかる Web サービス
実際のプログラムでは、完了までに時間がかかる Web サービスは次のような文になることがあります
。
2public void TimeConsumingTask()
3{
4 ConnectToDataBase();
5 GetSomeValueFromDataBase();
6 CopySomeFilesFromDisk();
7 GetARemoteFile();
8}
このようにして、現在の進行状況の完了ステータスを決定するための補助メソッドをいくつか挿入できます。 setProgress(int) を使用して、現在の進行状況の完了パーセンテージを設定します。
1[WebMethod]
2public void 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() メソッドを使用します
。
2public int StartTimeConsumingTask()
3{
4 文字列 processKey = this.Context.Request.UserHostAddress;
5 文字列 threadLockKey = "スレッド" + this.Context.Request.UserHostAddress;
6 オブジェクト threadLock = this.Context.Cache[threadLockKey];
7 if (threadLock == null)
8 {
9 threadLock = 新しいオブジェクト();
10 this.Context.Cache[threadLockKey] = threadLock;
11 }
12
13 // ユーザーごとに実行できるタスクは 1 つだけです。
14 if (!Monitor.TryEnter(threadLock, 0))
15 -1 を返します。
16
17 DateTime startTime = DateTime.Now;
18
19 // 時間のかかるタスクをシミュレートします。
(int i = 1; i <= 100; i++) の場合は 20
21 {
22 // このタスクの進行状況を更新します。
23 this.Context.Cache[プロセスキー] = i;
24 スレッド.スリープ(70);
25}
26
27 モニター.終了(スレッドロック);
28
29 return (DateTime.Now - startTime).Seconds;
30}
31
進捗状況をクエリするための Web サービスは
実装が簡単で、キャッシュから進捗情報を取得するだけです:
1[WebMethod]
2public int GetProgress()
3{
4 文字列 processKey = this.Context.Request.UserHostAddress;
5 オブジェクトの進行状況 = this.Context.Cache[processKey];
6 if (進行状況 != null)
7 {
8 戻り値 (int)progress;
9}
10
11 は 0 を返します。
12}
クライアント側のプログレス バー (ProgressBar) コントロール
ステップ 1: Sys.UI.Control から継承
ProgressBar コントロールは、Atlas コントロールの基本クラス Sys.UI.Control から継承し、シールされたクラスとして宣言する必要があります (シールされたクラス。継承されなくなります) )。 Sys.UI.Control 基本クラスには、すべてのコントロールに共通のいくつかの操作とメソッドが含まれています。たとえば、自分自身を HTML 要素に関連付ける (バインディングとも呼ばれます) などです。同時に、たとえば、Atlas がこのタイプの説明を取得できるように、将来の宣言や使用のためにこの新しいタイプについて Atlas に知らせるために登録する必要があります。
1Sys.UI.ProgressBar = function(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 を作成します。
次に、コントロールを設定するためにいくつかのプロパティを追加する必要があります。この例では、次の 3 つのプロパティが必要です:
Interval: 進行状況が再クエリされてから進行状況バーが更新されるまでの間隔。単位:ミリ秒
サービス URL。Web サービス ファイルのパス。
サービスメソッド。進行状況情報を取得するメソッドの名前。
これらのプロパティは Atlas の命名規則に厳密に従う必要があります。Getter は 'get_' で始まり、Setter は 'set_' で始まりパラメータを渡す必要があります。また、コントロールの記述子にこれらのプロパティの説明を追加する必要があります。記述方法(ディスクリプタ)については第4ステップで説明する。たとえば、Service Method 属性の場合、次のステートメントがあります
。
2
3this.get_serviceMethod = function() {
4 return _serviceMethod;
5}
6
7this.set_serviceMethod = 関数(値) {
8 _serviceMethod = 値;
9}
ステップ 3: タイマー コントロールを使用して Web サービス
Sys を時々クエリします。タイマーは、毎回このメソッドを指すようにデリゲートを定義して実行することができます。期間内にこの Web サービスにクエリを実行します。ブラウザーのメモリ リークを避けるために、コントロールが破棄される (破棄される) ときに、必要なクリーンアップを忘れずに実行する必要があります。
また、前のリクエストが返されなかった場合は、2 番目のリクエストを送信しないでください。
1var _timer = 新しい 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 = function() {
14 if (_timer) {
15 _timer.tick.remove(_tickHandler);
16 _tickHandler = null;
17 _timer.dispose();
18}
19 _timer = null;
20 関連要素 = null;
21 _obj = null;
22
23 Sys.UI.ProgressBar.callBaseMethod(this, 'dispose');
24}
25
26this._onTimerTick = function(sender, eventsArgs) {
27 if (!_responsePending) {
28 _responsePending = true;
29
30 // サービス メソッドを非同期的に呼び出します。
31 Sys.Net.ServiceMethod.invoke(_serviceURL, _serviceMethod, null, null, _onMethodComplete);
32}
33}
34
35関数 _onMethodComplete(結果) {
36 // 進行状況バーを更新します。
37 _obj.set_progress(結果);
38 _responsePending = false;
39}
ステップ 4: 制御メソッドを追加する
プログレス バーの開始/停止を制御できるようにする必要があります。また、Atlas コントロールの場合は、関連する記述メソッド (ディスクリプタ) も必要です。 Atlas は、この種の情報を説明するためにこれを使用します。
1this.getDescriptor = function() {
2 var td = Sys.UI.ProgressBar.callBaseMethod(this, 'getDescriptor');
3 td.addProperty('間隔', Number);
4 td.addProperty('進捗状況', Number);
5 td.addProperty('serviceURL', String);
6 td.addProperty('serviceMethod', String);
7 td.addMethod('start');
8 td.addMethod('stop');
9 TD を返します。
10}
11
12this.start = function() {
13 _timer.set_enabled(true);
14}
15
16this.stop = function() {
17 _timer.set_enabled(false);
18}
OK、ここまででクライアント制御は完了です。これを ProgressBar.js として保存します。
ASP.NET テスト ページ ASP.NET テスト ページ
どの Atlas ページでも、最初に行う必要があるのは、ScriptManager サーバー コントロールを追加することです。この例では、ProgressBar コントロール、完了までに時間がかかる Web サービス、および Progress Query Web サービスを参照します。 (これら 2 つの Web サービスは同じファイル TaskService.asmx にあります)
1<atlas:ScriptManager ID="ScriptManager1" runat="server" >
2 <スクリプト>
3 <atlas:ScriptReference Path="ScriptLibrary/ProgressBar.js" ScriptName="Custom" />
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 幅: 500ピクセル;
8 高さ: 15px;
9}
10. プログレスバー {}{
11 背景色: 緑;
12 高さ: 15px;
13 幅: 0px;
14 フォントの太さ: 太字。
15}
16</style>
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="output" ></div>
最後に、Web サービスを開始する JavaScript の部分がありますが、これは完了して ProgressBar コントロールが動作し始めるまでに長い時間がかかります。
スクリーンショットとダウンロード
これですべてが完了し、実行する準備が整いました。
ページの初期化:
実行中:
実行が完了しました:
サンプルプログラムとソースファイルはここからダウンロードできます。