2

環境

物理マシン A でコンソールとして実行されている WCF サービス (NET:TCP | Reliable | SecurityEnabled) があります。

20 ~ 30 の .NET クライアント アプリケーション (Winforms) が Citrix 経由で公開されているため、サーバーとは別の 1 台の物理マシンで再度ホストされます。

問題

アプリケーションの構造は、 Juval Lowyによるhttp://msdn.microsoft.com/en-us/magazine/cc163537.aspxで説明されているのと同じパターンに従います。

問題は、サーバー側ではエラーなしでコールバックを呼び出すことができますが、クライアントはそれを受信しません。60 秒以内にコールバックが呼び出されない場合、再度サブスクライブを試行するコードがあります。サーバーで Subscribe API を呼び出して新しい接続を開くという副作用があります。一定期間にわたって、サーバー上で多数の TCP 接続が開いていることがわかります。エラーはありませんが、クライアント コールバックは呼び出されません。

追加情報

次のエラーがスローされることがあります。

00:01:00 の割り当てられたタイムアウト内にメッセージを転送できませんでした。信頼できるチャネルの転送ウィンドウに使用できるスペースがありませんでした。この操作に割り当てられた時間は、より長いタイムアウトの一部であった可能性があります。

さらに、以下のコードでわかるように、MaxBufferPoolSize は Int64.MaxValue に設定されます。

var binding = new NetTcpBinding(SecurityMode.Transport, reliableSession);
binding.ReliableSession.Enabled = true;
binding.ReliableSession.InactivityTimeout = TimeSpan.FromDays(1);
binding.ReliableSession.Ordered = true;
binding.CloseTimeout = TimeSpan.FromHours(1);
binding.SendTimeout = TimeSpan.FromHours(1);
binding.ReceiveTimeout = TimeSpan.FromHours(1);
binding.OpenTimeout = TimeSpan.FromHours(1);
binding.ReaderQuotas.MaxDepth = Int32.MaxValue;
binding.ReaderQuotas.MaxStringContentLength = Int32.MaxValue;
binding.ReaderQuotas.MaxArrayLength = Int32.MaxValue;
binding.ReaderQuotas.MaxBytesPerRead = Int32.MaxValue;
binding.ReaderQuotas.MaxNameTableCharCount = Int32.MaxValue;
binding.MaxBufferPoolSize = Int64.MaxValue;
binding.MaxReceivedMessageSize = Int32.MaxValue;

どんな提案でも大いに役立ちます!

4

2 に答える 2

3

最近の調査結果:

最近、クライアント側のコールバックには、ユーザー画面に表示される内容に基づいてさまざまな種類の処理があることを発見しました。これは、確認されるコールバックをブロックしていました。これは、バッファオーバーフローも説明しています。サーバーから送信される通知の頻度は、各クライアントが通知を処理するのにかかる時間と比較して非常に高くなっています。

セキュリティを無効にしたり、タイムアウトを正しく構成したりした変更とは別に、次のコード行が大いに役立ちました。

   public void OnNotification(AmigoMessage messsage)
    {
        ThreadPool.QueueUserWorkItem((x) => { ProcessNotification(messsage); });
    }
于 2013-02-28T12:16:30.837 に答える