Ejemplo n.º 1
0
 public async Task <byte[]> ReadAsync(ResponseReadingFinalizer responseReadingFinalizer, TimeSpan timeout)
 {
     using (var timeoutCancellationTokenSource = new CancellationTokenSource(timeout))
     {
         return(await ReadAsync(responseReadingFinalizer, timeoutCancellationTokenSource.Token, null));
     }
 }
Ejemplo n.º 2
0
 public async Task <byte[]> ReadAsync(ResponseReadingFinalizer responseReadingFinalizer, TimeSpan timeout, CancellationToken externalCancellationToken)
 {
     if (timeout == TimeSpan.Zero)
     {
         return(await ReadAsync(responseReadingFinalizer, null, externalCancellationToken));
     }
     else
     {
         using (var timeoutCancellationTokenSource = new CancellationTokenSource(timeout))
         {
             return(await ReadAsync(responseReadingFinalizer, timeoutCancellationTokenSource.Token, externalCancellationToken));
         }
     }
 }
Ejemplo n.º 3
0
        private async Task <byte[]> ReadAsync(ResponseReadingFinalizer responseReadingFinalizer, CancellationToken?timeoutCancellationToken, CancellationToken?externalCancellationToken)
        {
            EnsureOpened();

            Assure.ArgumentNotNull(responseReadingFinalizer, nameof(responseReadingFinalizer));
            if (timeoutCancellationToken == null && externalCancellationToken == null)
            {
                throw new ArgumentException($"At least either '{nameof(timeoutCancellationToken)}' or '{nameof(externalCancellationToken)}' should be passed.");
            }

            CancellationTokenSource linkedTokenSource = null;
            CancellationToken?      readContinuationTimeoutCancellationToken = null;

            try
            {
                try
                {
                    CancellationToken cancellationToken;
                    if (timeoutCancellationToken != null && externalCancellationToken != null)
                    {
                        linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeoutCancellationToken.Value, externalCancellationToken.Value);
                        cancellationToken = linkedTokenSource.Token;
                    }
                    else
                    {
                        cancellationToken = timeoutCancellationToken ?? externalCancellationToken.Value;
                    }

                    var responseBytes = new List <byte>();
                    var isFirstRead   = true;
                    // ReSharper disable LoopVariableIsNeverChangedInsideLoop
                    do
                    {
                        const int readBufferSize = 256;
                        byte[]    readBytes;

                        if (isFirstRead)
                        {
                            isFirstRead = false;

                            // wait with general cancellation token
                            readBytes = await _deviceIoPort.ReadAsync(readBufferSize, InputStreamOptions.Partial, cancellationToken);
                        }
                        else
                        {
                            // after first bytes are read, wait max 1s for the following ones
                            using (var readContinuationTimeoutCancellationSource = new CancellationTokenSource(TimeSpan.FromSeconds(1)))
                            {
                                readContinuationTimeoutCancellationToken = readContinuationTimeoutCancellationSource.Token;
                                using (var linkedContinuationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, readContinuationTimeoutCancellationToken.Value))
                                {
                                    readBytes = await _deviceIoPort.ReadAsync(readBufferSize, InputStreamOptions.Partial, linkedContinuationTokenSource.Token);
                                }
                            }
                        }

                        responseBytes.AddRange(readBytes);
                    }while (!responseReadingFinalizer(responseBytes));
                    // ReSharper restore LoopVariableIsNeverChangedInsideLoop

                    return(responseBytes.ToArray());
                }
                catch (OperationCanceledException)
                {
                    // rethrow specific token exception (for case of linked sources)
                    externalCancellationToken?.ThrowIfCancellationRequested();
                    timeoutCancellationToken?.ThrowIfCancellationRequested();
                    readContinuationTimeoutCancellationToken?.ThrowIfCancellationRequested();

                    throw new InvalidFlowStateException($"'{nameof(ReadAsync)}' - at least one of cancellation tokens should trigger exception.");
                }
            }
            catch (OperationCanceledException ex)
            {
                if (ex.CancellationToken == timeoutCancellationToken)
                {
                    throw new DeviceIoPortTimeoutException();
                }
                else if (ex.CancellationToken == readContinuationTimeoutCancellationToken)
                {
                    throw new DeviceIoPortTimeoutException(partialRead: true);
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                linkedTokenSource?.Dispose();
            }
        }
Ejemplo n.º 4
0
 public async Task <byte[]> ReadAsync(ResponseReadingFinalizer responseReadingFinalizer, CancellationToken externalCancellationToken)
 {
     return(await ReadAsync(responseReadingFinalizer, null, externalCancellationToken));
 }