6

PerCall に設定された WCF サービスがあります

クライアントから Start 呼び出しを送信して実行時間の長いプロセスを開始し、Cancel コマンドを送信してキャンセルする方法を知りたい

私のWCFサービスは次のようになります

 [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class Service1 : IService1
    {

        CancellationTokenSource cancelToken = new CancellationTokenSource();



        public void Start()
        {

            var compute = Task.Factory.StartNew(StartLongRunningTask, cancelToken.Token);
        }

        public void Stop()
        {

            cancelToken.Cancel();
        }

            private void StartLongRunningTask()
            {
                  //process here

            }

}

ここでの問題は、呼び出しがサーバーに着信するたびに、新しい要求として扱われることだと思います。

では、WCF で実行時間の長いタスクを開始およびキャンセルするにはどうすればよいでしょうか。

編集:Windowsサービスとしてホストしています

4

2 に答える 2

5

PerCall に設定された WCF サービスがあります

...ここでの問題は、呼び出しがサーバーに来るたびに、新しい要求として扱われることです。

うん、それはまさにあなたがそうするように言っていることです。可能であれば、InstanceContextMode.PerSession;に変更してください。その後、やろうとしていることを実行できます (セルフホスティングを想定しています)。

これができない場合は、@PeterRitchie がコメントしたような、より複雑なソリューションを開発する必要があります。まず、ホストです。IIS は、リクエストに関係なく長時間実行される操作を行うようには設計されていないため、自己ホストしていると仮定します。次に、長時間実行される操作の識別子として機能するトークンの形式 (GUID など) が必要になります。メソッドはGUIDStartを割り当てCancellationTokenSourceて操作を開始し、Stopメソッドは GUID を取得してそれを使用して を検索しCancellationTokenSource、操作をキャンセルします。ルックアップとして機能するには、共有 (静的、スレッドセーフ) ディクショナリが必要です。

ホストIIS の場合、ソリューションはより複雑になります... :)

まず、IIS でホストされていないバックエンドが必要です。一般的な選択肢は、Azure ワーカー ロールまたは Win32 サービスです。次に、信頼できる通信メカニズム (Azure キュー、MSMQ、WebSphere など) が必要になります。次に、WCF-over-IIS サービスを構築して、Startメソッドに GUID 識別子を生成させ、メッセージをキューにドロップして処理を開始します。 . このStopメソッドは GUID を取得し、メッセージをキューにドロップして処理をキャンセルします。他のすべてのロジックはバックエンド サービスに移動されます。

于 2013-03-11T03:46:09.253 に答える
2

あなたが尋ねた方法から、クライアントはリクエストの非同期性を認識しているようです。

@StephenClearyと@PeterRitchieのポイントは優れていますが、最初のステップは、サービス/コントラクトをやり直して非同期サービスを適切に実装し、長時間実行される操作に情報/ハンドルを(クライアントに)通信する手段を追加することです。

フレームワークには、非同期プログラミングのいくつかのパラダイムが含まれています(すでに:-))が、WCFに関しては、方法:非同期サービス操作の実装にフォールバックします。

これにより、ある程度のインフラストラクチャが提供されますが、必ずしも操作を自動的にキャンセルする機能は提供されません。

キャンセルについて厳密に言えば(これはあなたの質問です):あなたはあなたの解決策がキャンセルのためになるものは何でも延長しなければなりません。少なくとも、キャンセルトークンを監視して尊重するために、サービスの「ワーカー」に必要なロジックを追加する必要があります。

あなたが遭遇することを期待するかもしれない他の考慮事項:キャンセルからの結果を返す; なんとか完了したタスクをキャンセルする(キャンセル要求が来るまでに1,000,000レコードを更新したのは何ですか)。例外処理(タスクベースのプログラミング例外はスローされませんが、タスク、または進行中の操作を説明するために使用するその他の「手段」にバンドルされます)。

于 2013-03-11T05:09:12.397 に答える