private async Task <bool> ReadPackage(Dictionary <ReadItem, S7DataItemSpecification> result, ReadPackage normalized) { var id = GetNextReferenceId(); using (var dgmem = S7ReadJobDatagram.TranslateToMemory(S7ReadJobDatagram.BuildRead(_s7Context, id, normalized.Items), out var dgmemLength)) { using (var sendData = _transport.Build(dgmem.Memory.Slice(0, dgmemLength), out var sendLength)) { try { IEnumerable <S7DataItemSpecification> readResults = null; CallbackHandler <IEnumerable <S7DataItemSpecification> > cbh; using (await SemaphoreGuard.Async(_concurrentJobs).ConfigureAwait(false)) { cbh = new CallbackHandler <IEnumerable <S7DataItemSpecification> >(id); _readHandler.TryAdd(cbh.Id, cbh); try { if (await _transport.Client.SendAsync(sendData.Memory.Slice(0, sendLength)).ConfigureAwait(false) != SocketError.Success) { return(false); } readResults = await cbh.Event.WaitAsync(_s7Context.Timeout).ConfigureAwait(false); } finally { _readHandler.TryRemove(cbh.Id, out _); } } HandlerErrorResult(id, readResults, cbh); BildResults(result, normalized, readResults); } catch (TaskCanceledException) { ThrowHelper.ThrowTimeoutException(); } } } return(true); }
private async Task <bool> ReadPackage(Dictionary <ReadItem, S7DataItemSpecification> result, ReadPackage normalized) { var id = GetNextReferenceId(); using (var dgmem = S7ReadJobDatagram.TranslateToMemory(S7ReadJobDatagram.BuildRead(_s7Context, id, normalized.Items), out var dgmemLength)) { using (var sendData = _transport.Build(dgmem.Memory.Slice(0, dgmemLength), out var sendLength)) { try { IEnumerable <S7DataItemSpecification> readResults = null; CallbackHandler <IEnumerable <S7DataItemSpecification> > cbh = null; try { if (_concurrentJobs == null) { return(false); } using (await SemaphoreGuard.Async(_concurrentJobs).ConfigureAwait(false)) { cbh = new CallbackHandler <IEnumerable <S7DataItemSpecification> >(id); if (_readHandler.TryAdd(id, cbh)) { _logger?.LogTrace("Read handler with id {id} was added.", id); try { if (await _transport.Connection.SendAsync(sendData.Memory.Slice(0, sendLength)).ConfigureAwait(false) != SocketError.Success) { // we cancel return false, because if on esend faild we expect also all other ones failed. _logger?.LogWarning("Could not send read package with reference <{id}>.", id); return(false); } readResults = await cbh.Event.WaitAsync(_s7Context.Timeout).ConfigureAwait(false); } finally { _readHandler.TryRemove(id, out _); _logger?.LogTrace("Read handler with id {id} was removed.", id); } } else { _logger?.LogWarning("Could not add read handler with reference <{id}>.", id); } } } catch (ObjectDisposedException) { if (cbh == null) { return(false); } } HandlerErrorResult(id, readResults, cbh); BildResults(result, normalized, readResults); } catch (TaskCanceledException) { ThrowHelper.ThrowTimeoutException(); } } } return(true); }
public async Task <IEnumerable <S7DataItemSpecification> > ReadAsync(IEnumerable <ReadItem> vars) { if (ConnectionState != ConnectionState.Opened) { throw new Dacs7NotConnectedException(); } var result = vars.ToDictionary(x => x, x => null as S7DataItemSpecification); foreach (var normalized in CreateReadPackages(_s7Context, vars)) { var id = GetNextReferenceId(); var sendData = DataTransferDatagram.TranslateToMemory( DataTransferDatagram.Build(_context, S7ReadJobDatagram.TranslateToMemory( S7ReadJobDatagram.BuildRead(_s7Context, id, normalized.Items))).FirstOrDefault()); try { IEnumerable <S7DataItemSpecification> readResults = null; using (await SemaphoreGuard.Async(_concurrentJobs)) { var cbh = new CallbackHandler <IEnumerable <S7DataItemSpecification> >(id); _readHandler.TryAdd(cbh.Id, cbh); try { if (await _socket.SendAsync(sendData) != SocketError.Success) { return(new List <S7DataItemSpecification>()); } readResults = await cbh.Event.WaitAsync(_timeout); } finally { _readHandler.TryRemove(cbh.Id, out _); } } if (readResults == null) { throw new TimeoutException(); } var items = normalized.Items.GetEnumerator(); foreach (var item in readResults) { if (items.MoveNext()) { if (items.Current.IsPart) { if (!result.TryGetValue(items.Current.Parent, out var parent) || parent == null) { parent = new S7DataItemSpecification { TransportSize = item.TransportSize, Length = items.Current.Parent.Length, Data = new byte[items.Current.Parent.Length] }; result[items.Current.Parent] = parent; } parent.ReturnCode = item.ReturnCode; item.Data.CopyTo(parent.Data.Slice(items.Current.Offset - items.Current.Parent.Offset, items.Current.Length)); } else { result[items.Current] = item; } } } } catch (TaskCanceledException) { throw new TimeoutException(); } } return(result.Values); }