/// <summary> /// Initializes a new instance of the <see cref="ConcurrentRequestExecutor"/> class with the specified /// connection and memory pool. /// </summary> /// <param name="connection">The <see cref="S7Connection"/> that is used for this executor.</param> /// <param name="memoryPool"> /// The <see cref="MemoryPool{T}" /> that is used for request and response memory allocations. /// </param> public ConcurrentRequestExecutor(S7Connection connection, MemoryPool <byte>?memoryPool = default) { if (connection.Parameters == null) { Sally7CommunicationSetupException.ThrowConnectionParametersNotSet(); } Connection = connection; socket = connection.TcpClient.Client; bufferSize = connection.Parameters.GetRequiredBufferSize(); maxRequests = connection.Parameters.MaximumNumberOfConcurrentRequests; this.memoryPool = memoryPool ?? MemoryPool <byte> .Shared; jobPool = new JobPool(connection.Parameters.MaximumNumberOfConcurrentRequests); sendSignal = new Signal(); receiveSignal = new Signal(); if (!sendSignal.TryInit()) { Sally7Exception.ThrowFailedToInitSendingSignal(); } if (!receiveSignal.TryInit()) { Sally7Exception.ThrowFailedToInitReceivingSignal(); } reader = new SocketTpktReader(socket); #if !NETSTANDARD2_1_OR_GREATER && !NET5_0_OR_GREATER sendAwaitable = new SocketAwaitable(new SocketAsyncEventArgs()); #endif }
/// <summary> /// Initializes a new instance of the <see cref="ConcurrentRequestExecutor"/> class with the specified /// connection and memory pool. /// </summary> /// <param name="connection">The <see cref="S7Connection"/> that is used for this executor.</param> /// <param name="memoryPool"> /// The <see cref="MemoryPool{T}" /> that is used for request and response memory allocations. /// </param> public ConcurrentRequestExecutor(S7Connection connection, MemoryPool <byte> memoryPool) { if (connection.Parameters == null) { throw new ArgumentException( "The connection must be initialized and it's Parameters property must have a value."); } Connection = connection; socket = connection.TcpClient.Client; bufferSize = connection.Parameters.GetRequiredBufferSize(); maxRequests = connection.Parameters.MaximumNumberOfConcurrentRequests; this.memoryPool = memoryPool; var maxNumberOfConcurrentRequests = connection.Parameters.MaximumNumberOfConcurrentRequests; jobChannel = Channel.CreateBounded <byte>(maxNumberOfConcurrentRequests); sendChannel = Channel.CreateBounded <byte>(1); receiveChannel = Channel.CreateBounded <byte>(1); if (!Enumerable.Range(1, maxNumberOfConcurrentRequests).All(i => jobChannel.Writer.TryWrite((byte)i))) { throw new Exception($"Failed to initialize the job channel."); } if (!sendChannel.Writer.TryWrite(1)) { throw new Exception("Failed to initialize the sending channel."); } if (!receiveChannel.Writer.TryWrite(1)) { throw new Exception("Failed to initialize the receiving channel."); } requests = Enumerable.Range(0, maxNumberOfConcurrentRequests).Select(_ => new Request()).ToArray(); reader = new SocketTpktReader(socket); sendAwaitable = new SocketAwaitable(new SocketAsyncEventArgs()); }