私はWCFクライアント/サーバーアプリを開発しており、クライアントは呼び出しをラップTask.Factory.StartNew
し、継続を使用してWCF呼び出しからの戻り時にユーザー指定のデリゲートを呼び出すことにより、サーバーを非同期的に呼び出します。サーバー操作は、クライアントに応答を返す前に、いくつかのシリアル I/O を実行します。また、サービスは BlockingCollection を使用してこれらの要求をキューに入れ、シリアル ポートの競合を回避するために一度に 1 つずつ実行されるようにします。現状では、クライアントがサーバーに大量のリクエストを立て続けに発行した場合でも、アプリは完全に正常に動作します。
現在は、クライアントがサーバー側のアセンブリを直接参照する "ダイレクト" モードで実行するようにアプリを構成することもできます (クライアントとサーバーが同じ PC 上にある場合、パフォーマンス上の理由から)。このシナリオでは、クライアントは (ChannelFactory によって作成されたプロキシではなく) サービス クラスのインスタンスを使用し、同じ非同期Task.Factory.StartNew
ヘルパーを使用してその操作メソッドを直接呼び出します。
この「直接」モードでは、サーバー側の実行が何らかの方法で中断されているかのように、ゆっくりと実行されているように見えます (シリアル ポート データが失われます)。クライアント側のタスクを使用するように変更することで、「修正」できますTaskCreationOptions.LongRunning
。残念ながら、これは「WCFモード」のときにアプリを壊し、同じ速度の問題を抱えているようです。
ここで、アプリが使用している「モード」に応じて、単純に TaskCreationOptions を含める (または含めない) ことができますが、そもそもなぜこれが起こっているのかを理解したいと思います。何か案は?
編集:アプリの起動中に、クライアントが1ダースのリクエストをサーバーに次々と送信するときに問題に気づきました。for
ループ。この後、クライアントは 0.5 秒ごとにサーバーをポーリングします。これは問題の影響を受けません。また、クライアント側とサーバー側の両方で実行される他の 2 つのスレッド タイマー (そのうちの 1 つが 65 ミリ秒ごとに起動します!) も影響を受けません。スレッドプールは、スレッドの最小数に達するまで新しいスレッドを作成し、その後、作成されるスレッドの数を 500 ミリ秒ごとに 1 つに制限するという記事を見つけました。これは、約0.5秒ごとに速度が低下するのを見ているため、私の問題の症状と一致します。サーバーに何度も連続してヒットするのを避けるために、クライアント側のコードをリファクタリングしますが、これは残念です。私は本当にこれらすべてのリクエストを 1 つずつ開始し、サーバーによって処理された結果をコールバック デリゲートで処理したいと考えていました。しかし、このスレッドプールでは "