3

私はサーバー側で計算を行っているいくつかのソフトウェアに取り組んでいます。私はBackgroundWorkerを使用してみましたが、ファットクライアントからWebサービスに切り替えようとするまでは完全に正常に機能していました。「BackgroundWorkerはSerializableとしてマークされていません」というエラー(同僚の話ですでに予想していた)が発生しました。私のアプリケーションの目標は、計算の進行状況と現在計算されているレコードの名前でクライアントを更新することです。必要に応じてコードを投稿できますが、この場合、それが問題に本当に関連しているとは思えません。私が達成しようとしていることのスキームは、次のように示すことができます。

  • クライアントが「準備」ボタンを押す
  • サーバーが電話を受ける
  • サーバーがデータを送信します
  • クライアントは確認のためにレコードリストを受け取ります
  • クライアントが選択を確認します(次に、バックグラウンドワーカーを設定し、サーバーに送信します)
  • サーバーが呼び出しを取得します(バックグラウンドワーカーの参照と、一度に計算するために必要なすべてのレコードを受信します)
  • レコードを実行するループ(各計算には約1〜3秒かかります)を使用して、BackgroundWorkerのステータスを次のように更新します。

    worker.ReportProgress(i * 100 / ids.Length, "Currently counting: " + id + "...");
    Calculate(ids[i]);
    worker.ReportProgress((i+1) * 100 / ids.Length, "Currently counting: " + id + "...");
    

Webサービスでも作業しようとしていることを達成する方法はありますか? BackgroundWorkerをだましてSerializableにする必要があると思いますか、それともサーバーからクライアントにステータスを更新する他の方法がありますか?

PS私はサーバーからあまり多くのデータを送り返していません(実際にはidのみのようにさらに少ないデータを送信しようとすることもできます)ので、過負荷の問題にはならないと思います。

4

3 に答える 3

4

基本的に、Webのコードを作成するときは、継続的な対話ではなく、要求/応答に基づいて、まったく異なるモデルを処理します。

おそらく、最初のリクエストで一種の「タスクID」(任意の一意のID)を返し、それをすばやく返す必要があります。その間、バックグラウンドでタスクを開始します。その後、クライアントはその特定のタスクのステータスをポーリングできます。ステータスが変更されるまで各リクエストがハングアップする「ロングポーリング」を使用するか、クライアントに定期的にサーバーを呼び出させることができます。いずれにせよ、応答は進行状況(処理されたレコードの数と現在のレコードの名前)だけになります。

于 2012-10-18T07:05:21.833 に答える
0

バックグラウンドワーカーのメンバー変数を持つクラスのインスタンスをシリアル化しようとしているのではないかと思います。バックグラウンドワーカーはシリアル化可能なオブジェクトではないため、これを行うことはできません。

ここでできることは-

  • 非同期で実行されるメソッドを持つクラスを作成します。
  • バックグラウンドワーカーの進行状況を格納するメンバー変数をそのクラスに作成します
  • 進行状況の値を返すWebメソッドをクラスに作成します。

今あなたのページであなたはする必要があります

  • 非同期で実行する必要があるメソッドを呼び出します。
  • 定期的に実行されるクライアント側のJavaScriptを配置します。Webサービスにクエリを実行し、進行状況を確認する必要があります。
    • ページを更新して進行状況を表示します。

きちんと説明できたと思います。

于 2012-10-18T07:07:45.737 に答える
0

サービスのプロセスを随時(マイルストーンの完了時に)更新したい場合は、非同期サービスを使用することをお勧めします。WCFを使用して、非同期のサービスを作成します(次のようなトピックを参照してください:http://blogs.msdn.com/b/rjacobs/archive/2011/06/30/how-to-implement-a-wcf-非同期サービス操作-with-task-lt-t-gt.aspx)。

次のようなメソッドを作成します

public int onBlockComplete(IAsyncResult result)
{
    //...
}

そして、これをクライアントで処理します。また、プロセス全体が完了したときにコールバックするメソッドを実装します。

このようにして、ブロック完了イベントを処理し、クライアントに進行状況を表示できます。

もちろん、クライアントをASP.NETに実装する場合は、更新を確認するためにページを更新する必要があります。

于 2012-10-18T07:10:14.567 に答える