public static void Main(string[] args)
        {
            try
            {
                ApplicationInstance.MessageDlg = new ApplicationMessageDlg();
                ApplicationInstance application = new ApplicationInstance();
                application.ApplicationName   = "Manufacturing Execution System";
                application.ApplicationType   = ApplicationType.Client;
                application.ConfigSectionName = "Opc.Ua.MES";

                // load the application configuration.
                ApplicationConfiguration appConfiguration = application.LoadApplicationConfiguration(false).Result;

                // check the application certificate.
                application.CheckApplicationInstanceCertificate(false, 0).Wait();

                // get list of cached endpoints.
                ConfiguredEndpointCollection endpoints = appConfiguration.LoadCachedEndpoints(true);
                endpoints.DiscoveryUrls = appConfiguration.ClientConfiguration.WellKnownDiscoveryUrls;

                StationsCollection collection = StationsCollection.Load(appConfiguration);
                if (collection.Count > 0)
                {
                    m_station = collection[0];
                }
                else
                {
                    throw new ArgumentException("Could not load station definition from configuration file!");
                }

                // connect to all servers.
                m_sessionAssembly  = EndpointConnect(endpoints[c_Assembly], appConfiguration);
                m_sessionTest      = EndpointConnect(endpoints[c_Test], appConfiguration);
                m_sessionPackaging = EndpointConnect(endpoints[c_Packaging], appConfiguration);

                if (!CreateMonitoredItem(m_station.StatusNode, m_sessionAssembly, new MonitoredItemNotificationEventHandler(MonitoredItem_AssemblyStation)))
                {
                    Trace("Failed to create monitored Item for the assembly station!");
                }
                if (!CreateMonitoredItem(m_station.StatusNode, m_sessionTest, new MonitoredItemNotificationEventHandler(MonitoredItem_TestStation)))
                {
                    Trace("Failed to create monitored Item for the test station!");
                }
                if (!CreateMonitoredItem(m_station.StatusNode, m_sessionPackaging, new MonitoredItemNotificationEventHandler(MonitoredItem_PackagingStation)))
                {
                    Trace("Failed to create monitored Item for the packaging station!");
                }

                StartAssemblyLine();

                // MESLogic method is executed periodically, with period c_updateRate
                RestartTimer(c_updateRate);

                Trace("MES started. Press any key to exit.");

                try
                {
                    Console.ReadKey(true);
                }
                catch
                {
                    // wait forever if there is no console, e.g. in docker
                    Thread.Sleep(Timeout.Infinite);
                }
            }
            catch (Exception ex)
            {
                Trace("Critical Exception: {0}, MES exiting!", ex.Message);
            }
        }
        public static void Main(string[] args)
        {
            try
            {
                ApplicationInstance.MessageDlg = new ApplicationMessageDlg();
                ApplicationInstance application = new ApplicationInstance();
                application.ApplicationName   = "Manufacturing Execution System";
                application.ApplicationType   = ApplicationType.Client;
                application.ConfigSectionName = "Opc.Ua.MES";

                // load the application configuration.
                ApplicationConfiguration appConfiguration = application.LoadApplicationConfiguration(false).Result;

                // check the application certificate.
                application.CheckApplicationInstanceCertificate(false, 0).Wait();

                // get list of cached endpoints.
                ConfiguredEndpointCollection endpoints = appConfiguration.LoadCachedEndpoints(true);
                endpoints.DiscoveryUrls = appConfiguration.ClientConfiguration.WellKnownDiscoveryUrls;

                StationsCollection collection = StationsCollection.Load(appConfiguration);
                if (collection.Count > 0)
                {
                    m_station = collection[0];
                }
                else
                {
                    throw new ArgumentException("Can not load station definition from configuration file!");
                }

                // connect to all servers.
                m_sessionAssembly  = new SessionHandler();
                m_sessionTest      = new SessionHandler();
                m_sessionPackaging = new SessionHandler();

                DateTime retryTimeout = DateTime.UtcNow + TimeSpan.FromMilliseconds(c_connectTimeout);
                do
                {
                    try
                    {
                        m_sessionAssembly.EndpointConnect(endpoints[c_Assembly], appConfiguration);
                        m_sessionTest.EndpointConnect(endpoints[c_Test], appConfiguration);
                        m_sessionPackaging.EndpointConnect(endpoints[c_Packaging], appConfiguration);
                    }
                    catch (Exception ex)
                    {
                        Trace("Exception connecting to assembly line: {0}, retry!", ex.Message);
                    }

                    if (DateTime.UtcNow > retryTimeout)
                    {
                        throw new Exception(String.Format("Failed to connect to assembly line for {0} seconds!", c_connectTimeout / 1000));
                    }
                    System.Threading.Thread.Sleep(c_waitTime);
                }while (!(m_sessionAssembly.SessionConnected && m_sessionTest.SessionConnected && m_sessionPackaging.SessionConnected));

                if (!CreateMonitoredItem(m_station.StatusNode, m_sessionAssembly.Session, new MonitoredItemNotificationEventHandler(MonitoredItem_AssemblyStation)))
                {
                    throw new Exception("Failed to create monitored Item for the assembly station!");
                }
                if (!CreateMonitoredItem(m_station.StatusNode, m_sessionTest.Session, new MonitoredItemNotificationEventHandler(MonitoredItem_TestStation)))
                {
                    throw new Exception("Failed to create monitored Item for the test station!");
                }
                if (!CreateMonitoredItem(m_station.StatusNode, m_sessionPackaging.Session, new MonitoredItemNotificationEventHandler(MonitoredItem_PackagingStation)))
                {
                    throw new Exception("Failed to create monitored Item for the packaging station!");
                }

                StartAssemblyLine();

                // MESLogic method is executed periodically, with period c_updateRate
                RestartTimer(c_updateRate);

                Trace("MES started. Press Ctrl-C to exit.");

                m_quitEvent = new ManualResetEvent(false);
                try
                {
                    Console.CancelKeyPress += (sender, eArgs) => {
                        m_quitEvent.Set();
                        eArgs.Cancel = true;
                    };
                }
                catch
                {
                }

                // wait for MES timeout or Ctrl-C
                m_quitEvent.WaitOne();
            }
            catch (Exception ex)
            {
                Trace("Critical Exception: {0}, MES exiting!", ex.Message);
            }
        }