2

winform の wcf プロキシに問題があります。この wcf サービスは IIS でホストされ、2 つのメソッドを公開し、シングル スレッドの winform (一度に 1 つの呼び出し) で使用しているときに正常に動作します。異なるスレッドで同じプロキシ (同じインスタンスまたは 2 つの個別のインスタンス、それは問題ではありません) を使用すると、問題が発生します。「安全なハンドルが閉じられました」というエラーが表示されます。

私が本当に理解していないのは、すべてが同じ wcf メソッドを呼び出すいくつかのスレッドを開始すると、正常に動作するということです。この問題は、wcf メソッドのいずれかへの呼び出しを開始し、2 番目の wcf メソッドへの別の呼び出しを開始し、最初の呼び出しが完了する前にこの 2 番目の呼び出しが終了した場合にのみ発生します。明確にするために:

This will work:
    - start threadA that calls wcf MethodA
    - start threadB that calls wcf MethodA
    - MethodA in threadA finishes <-- No errors
    - MethodA in threadB finishes <-- No errors

This won't work:
    - start threadA that calls wcf MethodA
    - start threadB that calls wcf MethodB
    - MethodB in threadB finishes <-- No errors
    - MethodA in threadA finishes <-- Error "Safe handle has been closed"

This won't work either, methods order doesn't matter, only the fact that I mix methods it seems:
    - start threadA that calls wcf MethodB
    - start threadB that calls wcf MethodA
    - MethodA in threadB finishes <-- No errors
    - MethodB in threadA finishes <-- Error "Safe handle has been closed"

これは私が受け取っているスタックです:

Server stack trace:
   at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at MyProxy.MyInterface.MyMethod(String myParam)

誰か説明がありますか?

4

1 に答える 1

0

通常、すべてのプロキシ クラスは System.ServiceModel.ClientBase から派生します。MSDN のドキュメントによると、ClientBase のインスタンス メソッドはスレッド セーフではありません。

http://msdn.microsoft.com/en-us/library/ms576141.aspx

また、エラーを見ると、サービスに共通のリソースがある可能性があります。MethodA と MethodB が共通のリソースにアクセスしているかどうかを確認してください。デバッグサービスが役立ちます

于 2013-02-27T15:07:06.820 に答える