/// <summary> /// Shutdown all sessions. /// </summary> public async static Task SessionShutdownAsync() { try { while (OpcSessions.Count > 0) { OpcSession opcSession = null; try { await OpcSessionsListSemaphore.WaitAsync(); opcSession = OpcSessions.ElementAt(0); OpcSessions.RemoveAt(0); } finally { OpcSessionsListSemaphore.Release(); } await opcSession?.ShutdownAsync(); } } catch (Exception e) { Logger.Fatal(e, "Failed to shutdown all sessions."); } // Wait and continue after a while. uint maxTries = ShutdownWaitPeriod; while (true) { int sessionCount = OpcSessions.Count; if (sessionCount == 0) { return; } if (maxTries-- == 0) { Logger.Information($"There are still {sessionCount} sessions alive. Ignore and continue shutdown."); return; } Logger.Information($"{ProgramName} is shutting down. Wait {SessionConnectWaitSec} seconds, since there are stil {sessionCount} sessions alive..."); await Task.Delay(SessionConnectWaitSec * 1000); } }
/// <summary> /// Create the data structures to manage OPC sessions and actions. /// </summary> /// <returns></returns> public static async Task <bool> CreateOpcActionDataAsync() { try { await OpcActionListSemaphore.WaitAsync(); await OpcSessionsListSemaphore.WaitAsync(); // create actions out of the configuration var uniqueEndpointUrls = _actionConfiguration.Select(n => n.EndpointUrl).Distinct(); foreach (var endpointUrl in uniqueEndpointUrls) { // create new session info. OpcSession opcSession = new OpcSession(endpointUrl, _actionConfiguration.Where(n => n.EndpointUrl == endpointUrl).First().UseSecurity, OpcSessionCreationTimeout); // add all actions to the session List <OpcAction> actionsOnEndpoint = new List <OpcAction>(); var endpointConfigs = _actionConfiguration.Where(c => c.EndpointUrl == endpointUrl); foreach (var config in endpointConfigs) { config?.Read.ForEach(r => opcSession.OpcActions.Add(new OpcReadAction(r))); config?.Write.ForEach(w => opcSession.OpcActions.Add(new OpcWriteAction(w))); } // add session. OpcSessions.Add(opcSession); } } catch (Exception e) { Logger.Fatal(e, "Creation of the internal OPC management structures failed. Exiting..."); return(false); } finally { OpcSessionsListSemaphore.Release(); OpcActionListSemaphore.Release(); } return(true); }