私は ASP.NET Web サービスを持っています。これは、いくつかのファイル操作や、一連の Crystal レポートからの Excel シートの生成など、重い作業を行うものです。このWebサービスを呼び出してブロックされたくないので、Webサービスの呼び出しを非同期にしたいです。また、この Web サービスを Web ページから呼び出したいのですが、サーバーのポーリングを継続できるメカニズムが必要です。これにより、進行状況のインジケーターを画面に表示できます。処理されました。Web メソッド呼び出しの完了に関する通知は必要ないことに注意してください。むしろ、ライブの進行状況が必要です。どうすればいいですか?
6 に答える
スケジュールされたジョブの ID を渡すことでクエリを実行できる別のメソッドをサーバーに記述し、0 から 100 (または 0.0 と 1.0 など) の概算値を返します。
http://yourserver.com/app/jobstatus/4133/
たとえば、REST スタイルでは、単純な '52' を として返すGET リクエストを作成できますtext/plain
。次に、(秒? 2 秒? 10 秒?) ごとにクエリを実行して、それがどれだけ進んでいるかを確認する必要があります。
バックエンドでの監視を実際にどのように行うかは、プロセスの内容とその動作に大きく依存します。
XML Webサービスは遅いと思うので、複数のメソッドの作成と進行状況のポーリングは非常に遅く、サーバーに大きな負荷がかかります。実稼働環境では行いません。データベースのポーリングでも同じ(ただし小さい)問題が発生します。
代わりにSOAP拡張機能を試してください。イベント駆動型モデルを実装します。MSDNの「Webサービスクライアントアプリケーションへのプログレスバーの追加」を参照してください。
SoapExtensionsを使用して、クライアントにダウンロード/プロセスの進行状況を通知することもできます。その後、サーバーはイベントをクライアントに送信できます。クライアントを使用しない場合は、何も変更する必要はありません。
クライアントで次のようなことができます。
//...
private localhost.MyWebServiceService _myWebService = new localhost.MyWebServiceService ();
_myWebService.processDelegate += ProgressUpdate;
_myWebService.CallHeavyMethod();
//...
private void ProgressUpdate(object sender, ProgressEventArgs e)
{
double progress = ((double)e.ProcessedSize / (double)e.TotalSize) * 100.00;
//Show Progress...
}
最初の「レポート生成の開始」Web サービス呼び出しでタスク プールにタスクを作成し、呼び出し元にタスクの ID を返します。
次に、特定の taskId の「完了率」を返す別のメソッドを提供します。
完了したタスクの実際の結果を返す 3 番目のメソッドを提供します。
最も簡単な方法は、呼び出しの進行状況に応じて Web サービスでデータベースのフィールドを更新し、そのフィールドを照会して値を返す Web サービスを作成することです。
Web サービスが何らかのタスク ID またはセッション ID を返すようにします。その ID でクエリを実行する別の Web メソッドを作成します。これにより、必要な情報 (完了率、ファイルのリストなど) が返されます。クライアントから一定の間隔でこのメソッドをポーリングします。
データベースを使用してプロセス情報を保存します。これを Web サービスのメモリ内で行うと、ポーリングしているサーバーとは別のサーバーでタスクが実行される可能性があるため、Web ファーム環境では適切にスケーリングされません。
編集:別の同様の回答を見て、コメントしました。コメンターは正しいです-メモリ内テーブルを使用してディスク操作を回避できますが、それでも別のdbサーバーを使用します。