1

私の WCF サービスは netTcpBinding を使用し、コールバック オブジェクトを持っています。

複数の同時クライアントにサービスを提供し、セッションを維持する必要があるため、サービスは次のように装飾されています

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple]

スレッドのデッドロックを回避するために、コールバック クラスは次のように装飾されています。

[CallbackBehavior(UseSynchronizationContext=false)]

SynchronizationContextUIスレッドでメソッドを実行するために使用します。

問題は、チャネルが理由もなく閉じられる場合があることです (ICommunicationObject.Closingイベントが発生します)。その後、後続のサービス呼び出しで例外が発生します。

トレース ファイルを見ると、最後のメッセージはコールバック コールですが、コールバック メソッドは呼び出されません。例外はありません。

いくつかのデバッグの後、これは同期操作の途中でコールバック呼び出しが行われた場合にのみ発生することがわかりました。手順は次のとおりです。

  1. Aを使用したサービス メソッドへの呼び出しIsOneWay=true
  2. Bを使用したサービス メソッドへの呼び出しIsOneWay=false
  3. Aコールバック メソッドを呼び出しますが、Bまだ実行中です。

コールバックにはUseSynchronizationContext=false.

単純なシナリオでは問題を再現できませんでした。単純なプロジェクトでこれらの手順を実行すると、正常に実行されます。

何が起こっているのか、または問題を特定する方法について何か考えはありますか?

4

3 に答える 3

10

クライアントが応答メッセージを期待していたときにコールバック メッセージを受信したため、クライアントがチャネルに障害を起こしている可能性が高いと思います。net.tcp を使用する WCF では、コールバックと応答で同じチャネルが使用されます。

原則として、要求/応答 (IsOneWay=false) の OperationContract メソッドの本体内でコールバック メソッドを呼び出すことはできません。最も安全な方法は、二重化を行うときにコントラクトに要求/応答メソッドをまったく持たないことですが、戻る前にコールバック コントラクトにコールバックしない限り、それらを安全に持つことができます。(たとえば、別のワーカー スレッドから戻った後にコールバック メソッドを呼び出しても問題ありません)。

于 2009-11-20T20:39:57.057 に答える
0

WCFラッパークラスの先頭に次の属性を追加する必要があります。

[CallbackBehavior(UseSynchronizationContext=false)]

cauldwell.netから:

問題は、ASP.NETが(デフォルトで)SynchronizationContextと呼ばれる小さなものを使用することでした。私が知る限り(正直に言うと、これについては徹底的に調査していません)、コールバックがUIスレッドで実行されるようにするのが仕事のひとつであり、それによってControlを呼び出す必要がなくなります。 WinForms。私の場合、その追加のロックは何かに合うものを与えていて、それはもう周りにないスレッド、つまりNullReferenceExceptionをクリーンアップしようとしていました。

于 2012-07-11T06:08:11.023 に答える
0

返信ありがとうございます。エラーを解決できました。

これはシリアライゼーションの問題でしたIncludeExceptionsInFaults=true。サービスとコールバックの動作属性を追加したところ、エラーが表示されました。

問題は、オブジェクト型の列を含む DataTable を送信していたことです。

于 2009-11-25T11:40:27.177 に答える