locked
MS CRM Online: Service throws ObjectDisposedException: Cannot Access a disposed object in production, while test works fine RRS feed

  • Question

  • Hi!

    I've encountered a rather strange problem with my OrganizationServiceProxy object.

    I have a Windows Service which reads records from at data warehouse, and pushes them to an MSCRM Online instance.

    The service does the following:

    1) Establishes the connection

    2) Retrieves the metadata information from CRM Online, and builds the entities based on the metadata

    3) Maps columns between the data warehouse and CRM

    4) Pushes the data using ExecuteMultiple

    The strange thing is that the service breaks on a RetrieveMultiple - query:

    ERROR 2014-01-30 09:02:12,238 614677ms Logger                 Run                - System.ObjectDisposedException: Cannot access a disposed object.
    Object name: 'System.ServiceModel.Security.TransportSecurityProtocol'.

    Server stack trace: 
       at System.ServiceModel.Channels.CommunicationObject.ThrowIfClosedOrNotOpen()
       at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout)
       at System.ServiceModel.Security.SecurityProtocol.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 Microsoft.Xrm.Sdk.IOrganizationService.RetrieveMultiple(QueryBase query)
       at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.RetrieveMultipleCore(QueryBase query)
       at MSCRM.IntegrationService.CrmOperations.GetAllRecords(String entityName)
       at MSCRM.IntegrationService.CrmOperations.BuildRequestList(EntityCollection entities, String entityName, String primaryKeyAttribute, String primaryKeyAttributeType)
       at MSCRM.IntegrationService.IntegrationService.Run()

    Before this error, the service has completed several calls to the organizationserviceproxy in order to retrieve the metadata. It occurs on the exact same place.

    Running the service in Test using the same MS CRM online instance does not cause the same problems

    The OrganizationServiceProxy is accessed from a property:

    internal static OrganizationServiceProxy Proxy { get { if (_proxy == null) { _proxy = Connection.GetProxy(); } return _proxy; } }

    public static OrganizationServiceProxy GetProxy()
            {
                IServiceManagement<IDiscoveryService> serviceManagement = ServiceConfigurationFactory.CreateManagement<IDiscoveryService>(new Uri(Properties.DiscoveryServiceAddress));
                AuthenticationProviderType endpointType = serviceManagement.AuthenticationType;
    
                AuthenticationCredentials authCredentials = GetCredentials(endpointType);
    
                String organizationUri = String.Empty;
                using (DiscoveryServiceProxy discoveryProxy = GetProxy<IDiscoveryService, DiscoveryServiceProxy>(serviceManagement, authCredentials))
                {
                    if (discoveryProxy != null)
                    {
                        OrganizationDetailCollection orgs = DiscoverOrganizations(discoveryProxy);
                        organizationUri = FindOrganization(Properties.OrganizationName, orgs.ToArray()).Endpoints[EndpointType.OrganizationService];
                    }
                }
                if (!String.IsNullOrWhiteSpace(organizationUri))
                {
                    IServiceManagement<IOrganizationService> orgServiceManagement =ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(organizationUri));
    
                    AuthenticationCredentials credentials = GetCredentials(endpointType);
                    //Set OrganizationServiceProxy
                    return GetProxy<IOrganizationService, OrganizationServiceProxy>(orgServiceManagement, credentials);
                }
                throw new Exception("Failed to establish OrganizationServiceProxy");
            }


    This method causes the error to be thrown:

    internal static Dictionary<Guid, Entity> GetAllRecords(string entityName)
            {
                //Get Attribute Typecode of primaryKeyColumn
                //AttributeTypeCode attributeTypeCode = GetAttributeTypeCode(entityName, primaryKeyColumn);
    
                int fetchCount = 5000;
                int pageNumber = 1;
                var results = new Dictionary<Guid, Entity>();
                QueryExpression pagequery = new QueryExpression();
                pagequery.EntityName = entityName;
                pagequery.ColumnSet.AllColumns = true; //Not exactly best performance, creating an awfully big soap envelope. Possible improvement. Add values for primarykey name and type in mappings.xml
    
                pagequery.PageInfo = new PagingInfo();
                pagequery.PageInfo.Count = fetchCount;
                pagequery.PageInfo.PageNumber = pageNumber;
    
                pagequery.PageInfo.PagingCookie = null;
    
                while (true)
                {
                    // Retrieve the page.
                    EntityCollection ec = Properties.Proxy.RetrieveMultiple(pagequery);
    
                    if (ec.Entities != null)
                    {
                        // Retrieve all records from the result set.
                        foreach (Entity entity in ec.Entities)
                        {
                            //Add to results dictionary
                            results.Add(entity.Id, entity);
                        }
                    }
    
                    // Check for more records, if it returns true.
                    if (ec.MoreRecords)
                    {
                        pagequery.PageInfo.PageNumber++;
                        pagequery.PageInfo.PagingCookie = ec.PagingCookie;
                    }
                    else
                    {
                        break;
                    }
                }
                return results;
            }

    I use the exact same configuration in Test as in production. I use the same database, and the same CRM Online organization. The only difference is that I simulate the Windows Service run using a Unit Test in Test mode, while I run it as an actual windows service in production.

    If anyone have any suggestions on where to look in order to solve this issue I would be most grateful

    Thursday, January 30, 2014 8:19 AM

All replies

  • Hi Torstein, have you found a solution to this?

    I'm experiencing this problem since last week in a very similar scenario.

    The only thing I changed (which is a big change) from the moment my site was working and now that I'm experiencing this issue, is that before I was using Early Bound types, but because of performance problems, I changed the code to use Late Bound types. I receive this error from time to time, it's not always.

    Please, let me know your experience.

    Thanks,

    Ale


    Dynamics CRM Certified Consultant (MB2-631,632,633)

    Monday, November 10, 2014 2:05 PM
  • Hi Torstein,
    Try to test the _proxy with some small request before sending it to main function where you using it actually...
    Below is the:
            internal static OrganizationServiceProxy Proxy
            {
                get
                {
                    if (_proxy == null)
                        _proxy = Connection.GetProxy();
                    try 
    	            {	        
    		            WhoAmIResponse _res = ((WhoAmIResponse)_proxy.Execute(new WhoAmIRequest()));
                        //.....//Test the _proxy with "WhoAmIRequest"...
    	            }
    	            catch (Exception)
    	            {
                        //If WhoAmIRequest FAILS, it would be due to "_proxy" object destroyed.
    		            return _proxy = Connection.GetProxy(); // So, just get new object from GetProxy() and return that newly created alive object.
    	            }
                    return _proxy;
                }
            }


    Monday, November 10, 2014 3:03 PM