2012-04-04 20 views
4

問題が発生しているWCFクライアントがあります。
時々、私はこの例外を受け取ります:Cannot access a disposed object。これは私が接続をオープンしています方法です:あなたが見ることができるように、私は閉じて、接続のたびに再オープンしています廃棄オブジェクトにアクセスできない - wcfクライアント

private static LeverateCrmServiceClient crm = null; 

public static CrmServiceClient Get(string crmCertificateName) 
     { 

      if (crm != null) 
      { 
       crm.Close(); 
      } 
      try 
      { 
       crm = new LeverateCrmServiceClient("CrmServiceEndpoint"); 
       crm.ClientCredentials.ClientCertificate.SetCertificate(
           StoreLocation.LocalMachine, 
           StoreName.My, 
           X509FindType.FindBySubjectName, 
           crmCertificateName); 
      } 
      catch (Exception e) 
      { 
       log.Error("Cannot access CRM ", e); 
       throw; 
      } 
      return crm; 
     } 

。 あなたはどう思われるでしょうか?

スタック:

System.ServiceModel.Security.MessageSecurityException: Message security verification failed. ---> System.ObjectDisposedException: Cannot access a disposed object. 
Object name: 'System.ServiceModel.Security.SymmetricSecurityProtocol'. 
    at System.ServiceModel.Channels.CommunicationObject.ThrowIfClosedOrNotOpen() 
    at System.ServiceModel.Security.MessageSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates) 
    --- End of inner exception stack trace --- 

Server stack trace: 
    at System.ServiceModel.Security.MessageSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates) 
    at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout) 
    at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout) 
    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 Externals.CrmService.ICrmService.GetTradingPlatformAccountDetails(Guid ownerUserId, String organizationName, String businessUnitName, Guid tradingPlatformAccountId) 
    at MyAppName.Models.ActionsMetadata.Trader.BuildTrader(Guid tradingPlatformAccountId) in C:\Users\X\Documents\Visual Studio 2010\Projects\MyAppName\MyAppName\Models\ActionsMetadata\Trader.cs:line 120 
    at MyAppName.Models.ActionsMetadata.Trader.Login(String accountNumber, String password) in C:\Users\X\Documents\Visual Studio 2010\Projects\MyAppName\MyAppName\Models\ActionsMetadata\Trader.cs:line 48 
    at MyAppName.Models.ActionsMetadata.Handlers.LoginHandler.Handle(StepHandlerWrapper wrapper) in C:\Users\X\Documents\Visual Studio 2010\Projects\MyAppName\MyAppName\Models\ActionsMetadata\Handlers\LoginHandler.cs:line 23 
    at MyAppName.Models.ActionsMetadata.Handlers.HandlerInvoker.Invoke(IAction brokerAction, ActionStep actionStep, Dictionary`2 stepValues, HttpContext httpContext, BaseStepDataModel model) in C:\Users\X\Documents\Visual Studio 2010\Projects\MyAppName\MyAppName\Models\ActionsMetadata\Handlers\StepServerInoker.cs:line 42 
    at MyAppName.Controllers.LoginController.Login(String step) in C:\Users\X\Documents\Visual Studio 2010\Projects\MyAppName\MyAppName\Controllers\LoginController.cs:line 35 
    at lambda_method(Closure , ControllerBase , Object[]) 
    at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) 
    at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
    at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() 
    at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) 
    at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
    at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) 
+0

これは、ここにanswerwedされているように見えます:発信者が発生する例外に関係なく、オブジェクトが配置された/閉じられていることを確認するためにusingステートメントを使用する必要がありますhttp://stackoverflow.com/questions/4573526/what -could-be-causing-a-can-accessible-a-object-wcfエラー – Chriseyre2000

答えて

6

そのスタックトレースから、私はあなたがGet方法はCrmServiceClientオブジェクトを取得することを呼び出して、いくつかのコードを使用してASP.NET MVCアプリケーションを持っていると仮定して、上のさまざまなメソッドを呼び出すに進み、そのCrmServiceClientオブジェクト。たとえば、ログインプロセスの一部がこれを行います。

Getメソッドの動作は、呼び出されるたびに先に返されたCrmServiceClientオブジェクトを(まだ使用されているかどうかにかかわらず)閉じ、新しいオブジェクトを作成して返します。

2人のユーザーが、ほぼ同時に同じ時間(1ミリ秒以内)でアプリケーションにログインしようとしたとします。最初のユーザのログインを処理するスレッドはGetを呼び出し、そのCrmServiceClientオブジェクトを取得し、その後1ミリ秒後に2番目のユーザのログインを処理するスレッドはGetを呼び出し、最初のスレッドのCrmServiceClientオブジェクトを閉じます。しかし、最初のスレッドはまだ実行されていて、今度はそれがCrmServiceClientオブジェクトのメソッドを呼び出そうとすると、それはSystem.ObjectDisposedException: Cannot access a disposed objectになります。

"ご覧のとおり、毎回接続を閉じて再オープンしています。"

現在、Getメソッドのコードは、これを実現する良い方法ではありません。代わりに、CrmServiceClientオブジェクトをクローズする(または破棄する)ことを発信者に任せてください。Getメソッドの名前をOpenまたはCreateに変更して、これを示す必要があります。

using (CrmServiceClient client = CrmServiceFactory.Get("my-crm-certificate")) 
{ 
    client.Something(); 
    client.GetTradingPlatformAccountDetails(); 
    client.SomethingElse(); 
} // client is automatically closed at the end of the 'using' block 
関連する問題