3

私は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 つずつ開始し、サーバーによって処理された結果をコールバック デリゲートで処理したいと考えていました。しかし、このスレッドプールでは "

4

2 に答える 2

1

LongRunning に切り替えることで問題が解決する場合は、LongRunning が設定されていない場合、タスク フレームワークがスレッド プールを使用するか、別のスレッドをまったく使用しないことを選択していることを意味します。

于 2012-08-31T14:45:27.613 に答える
0

いくつかのパフォーマンス ツールを実行するか、タイマーを接続して、ボトルネックがどこにあるかを調べることができます。または、名前付きパイプで WCF モードを使用します。(http://msdn.microsoft.com/en-us/library/ms733769.aspx)

于 2012-08-31T14:43:51.487 に答える