Cannot access a disposed object - wcf client

c#, objectdisposedexception, wcf-client

Solution

From that stack trace, I assume you have an ASP.NET MVC application with some code that calls that `Get` method to get a `CrmServiceClient` object, and then proceeds to call various methods on that `CrmServiceClient` object. For example, part of the login process does this.

The way your `Get` method works is, each time it is called, it will first close the `CrmServiceClient` object that it returned previously (regardless of whether or not it is still being used) then create and return a new one.

Imagine two users attempt to log in to your application at almost the same time - within milliseconds of each other. The thread handling the first user's login calls `Get` and gets its `CrmServiceClient` object, then a millisecond later the thread handling the second user's login calls `Get`, which causes the first thread's `CrmServiceClient` object to be closed. However, the first thread is still running, and now when it attempts to call a method on it's `CrmServiceClient` object, it gets a `System.ObjectDisposedException: Cannot access a disposed object`.

"As you can see, I am closing and reopening the connection each time."

The code currently in your `Get` method is not a good way to achive this. You should instead make it the caller's responsibility to close (or dispose) the `CrmServiceClient` object, and you should perhaps rename your `Get` method to `Open` or `Create` to suggest this. Callers should use a `using` statement to ensure that the object is closed/disposed, regardless of any exceptions that occur:

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

Problem

I have a WCF client that I'm having problems with. From time to time I am getting this exception: `Cannot access a disposed object`. This is how I am opening the connection: ``` 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; } ``` As you can see, I am closing and reopening the connection each time. What do you think might be the problem? Stack: ``` 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) ```

Original source

Related problems