1

タスクを永続的に保持し、WCF サービスから無期限に実行するのに苦労しています。私はこれを間違った方法で行っている可能性があり、提案を喜んで受け入れます。

BlockingCollection にドロップされた着信要求の処理を開始するタスクがあります。私が理解していることから、 GetConsumingEnumerable() メソッドを使用すると、データが到着したときに永続的にプルできるはずです。それ自体は問題なく動作します。Windowsフォームを使用してリクエストに記入し、送信することで、エラーや欠陥を1つも発生させることなく、数十のリクエストを処理することができました. このプロセスに自信が持てたら、asmx Web サービスを介して自分のサイトに接続し、jQuery ajax 呼び出しを使用してリクエストを送信しました。

サイトは送信された URL に基づいてリクエストを送信し、Web サービスは URL から html コンテンツをダウンロードし、コンテンツ内の他の URL を探します。次に、見つかった URL ごとにリクエストを作成し、BlockingCollection に送信します。WCF サービス内で、アプリケーションがオンラインの場合 (つまり、タスクが開始された場合)、Parallel.ForEach を介して GetConsumingEnumerable を使用して要求を取得し、要求を処理します。

これは最初のいくつかの送信では機能しますが、タスクは予期せず停止します。もちろん、これはテストでシミュレートできるよりも 10 倍多くのリクエストを実行していますが、スロットルするだけだと思っていました。問題は、タスクを開始する私の方法にあると思います:

 public void Start()
        {
            Online = true;

            Task.Factory.StartNew(() =>
            {
                tokenSource = new CancellationTokenSource();
                CancellationToken token = tokenSource.Token;
                ParallelOptions options = new ParallelOptions();
                options.MaxDegreeOfParallelism = 20;
                options.CancellationToken = token;

                try
                {
                    Parallel.ForEach(FixedWidthQueue.GetConsumingEnumerable(token), options, (request) =>
                    {
                        Process(request);
                        options.CancellationToken.ThrowIfCancellationRequested();

                    });
                }
                catch (OperationCanceledException e)
                {
                    Console.WriteLine(e.Message);
                    return;
                }

            }, TaskCreationOptions.LongRunning);

        }

これを WF4 サービスに移動し、ワークフローに接続してワークフローの永続性を使用することを考えましたが、必要でない限り WF4 を学習するつもりはありません。さらに情報が必要な場合はお知らせください。

4

2 に答える 2

1

あなたが示したコードはそれ自体で正しいです。

ただし、問題が発生する可能性があることがいくつかあります。

  • 例外が発生した場合、タスクは (もちろん) 停止します。try-catch を追加して、例外をログに記録してみてください。
  • ホストされた環境 (ASP.NET、WCF、SQL Server) でワーカー スレッドを開始すると、ホストは任意に (理由なく) 任意のワーカー プロセスをシャットダウンすることを決定できます。たとえば、ASP.NET サイトがしばらくアクティブでない場合、アプリはシャットダウンされます。先ほど言及したホストは、カスタム スレッドを実行するように作成されていません。おそらく、専用アプリケーション (.exe) または Windows サービスを使用すると、より多くの成功を収めることができます。
于 2012-05-27T13:31:02.093 に答える
0

この問題の原因は、WCF バインディング構成にあることがわかりました。オープン タイムアウトが原因で WCF が接続を切断したため、タスクが突然停止しました。オープン タイムアウト設定は、サービスが接続を開くのを要求がタイムアウトするまで待機する時間です。特定の状況では、10 個の最大接続の制限に達し、着信接続が接続を待機してバックアップされました。トランザクションが完了した後、ホストへのすべての接続を確実に閉じたので、最大接続数とオープン タイムアウト期間を増やすことにしました。この後、問題なく動作しました。

于 2012-05-28T18:47:23.300 に答える