2
Vote

Make the Singleton Thread-safe

description

In the event of high traffic on the CRM client, the multi-threaded nature of CRM and the Async service that processes the CRM plug-in code surfaces. This may result in instantiating more than one instance of the ConnectionSingleton and consequently more than one instance of the Axapta .NET Business Connector.
This may cause 'Already logged on' exceptions on the Axapta .NET Business Connector (which runs as part of the CRM Async service) and traffic mix-ups on the CRM side.
To solve this problem, use a Thread-Safe (of Multithreaded) Singleton with Double-Check locking.
 
{code:c#}
namespace AxWrapper
{
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Dynamics.BusinessConnectorNet;
 
namespace Connection
{
    /// <summary>
    /// The CRM 4 plug-in environment is Multi-Threaded.
    /// So we make this class Thread safe by implementing the 'Double-Check Locking' idiom.
    /// </summary>
    public sealed class AXConnectionSingelton : IDisposable
    {
        private static volatile AXConnectionSingelton instance;
        private static object syncRoot = new Object();
        private Axapta ax;
        private bool disposed = false;
 
        private AXConnectionSingelton()
        {
            ax = new Axapta();
        }
 
        public static AXConnectionSingelton Instance
        {
            get
            {
                if (instance == null) // Check
                {
                    lock (syncRoot) // serialize
                    {
                        if (instance == null) // Double-check
                            instance = new AXConnectionSingelton();
                    }
                }
 
                return instance;
            }
        }
 
        public Axapta connection()
        {
            return ax;
        }
 
        public void Dispose()
        {
            Dispose(true);
        }
 
        private void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if (!this.disposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged resources.
                if (disposing)
                {
                    // Dispose managed resources.
                    ax.Dispose();
                }
                instance = null;
                disposed = true;
            }
        }
    }
}
}
{code:c#}
 
Regards,
Patrick Fooij
CRM Developer ilionX.com

comments