public void OnReaderCompletedThrowsNotSupported()
        {
            PipeWriter writer = PipeWriter.Create(Stream.Null);

            Assert.Throws <NotSupportedException>(() => writer.OnReaderCompleted((_, __) => { }, null));
            writer.Complete();
        }
Пример #2
0
        public void OnReaderCompletedNoops()
        {
            bool       fired  = false;
            PipeWriter writer = PipeWriter.Create(Stream.Null);

            writer.OnReaderCompleted((_, __) => { fired = true; }, null);
            writer.Complete();
            Assert.False(fired);
        }
Пример #3
0
        private async Task CloneAsync(string path, PipeReader from, PipeWriter to)
        {
            try {
                to.OnReaderCompleted((ex, o) => {
                    // if (ex != null) Console.Error.WriteLine(ex);
                    ((PipeReader)o).Complete(ex);
                }, from);
                from.OnWriterCompleted((ex, o) =>
                {
                    // if (ex != null) Console.Error.WriteLine(ex);
                    ((PipeWriter)o).Complete(ex);
                }, to);
                try { File.Delete(path); } catch {}

                while (true)
                {
                    var result = await from.ReadAsync();

                    var buffer = result.Buffer;
                    if (result.IsCompleted && buffer.IsEmpty)
                    {
                        break;
                    }

                    using (var file = new FileStream(path, FileMode.Append, FileAccess.Write))
                    {
                        foreach (var segment in buffer)
                        {
                            // append it to the file
                            bool leased = false;
                            if (!MemoryMarshal.TryGetArray(segment, out var arr))
                            {
                                var tmp = ArrayPool <byte> .Shared.Rent(segment.Length);

                                segment.CopyTo(tmp);
                                arr    = new ArraySegment <byte>(tmp, 0, segment.Length);
                                leased = true;
                            }
                            await file.WriteAsync(arr.Array, arr.Offset, arr.Count);

                            await file.FlushAsync();

                            if (leased)
                            {
                                ArrayPool <byte> .Shared.Return(arr.Array);
                            }

                            // and flush it upstream
                            await to.WriteAsync(segment);
                        }
                    }
                    from.AdvanceTo(buffer.End);
                }
            }
            catch { }
        }
Пример #4
0
        private async Task WriteToConnection(
            PipeWriter output,
            CancellationToken token)
        {
            try
            {
                var reader = _writeChannel.Reader;
                output.OnReaderCompleted((err, state) =>
                {
                    _writeChannel.Writer.TryComplete(err);
                }, null);

                while (true)
                {
                    if (!await reader.WaitToReadAsync(token))
                    {
                        break;
                    }

                    if (!reader.TryRead(out var message))
                    {
                        continue;
                    }

                    var count = WriteOperationMessage(message, output);
                    output.Advance(count);

                    // apply back-pressure etc
                    var flush = await output.FlushAsync(token);

                    if (flush.IsCanceled || flush.IsCompleted)
                    {
                        break;
                    }
                }

                // Manifest any errors in the completion task
                await reader.Completion;
            }
            catch (Exception ex)
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }

                output.Complete(ex);
                throw;
            }
            finally
            {
                // This will safely no-op if the catch block above ran.
                output.Complete();
            }
        }
Пример #5
0
        public void OnReaderCompletedNoops()
        {
            bool       fired  = false;
            PipeWriter writer = PipeWriter.Create(Stream.Null);

#pragma warning disable CS0618 // Type or member is obsolete
            writer.OnReaderCompleted((_, __) => { fired = true; }, null);
#pragma warning restore CS0618 // Type or member is obsolete
            writer.Complete();
            Assert.False(fired);
        }
Пример #6
0
        internal static Task WaitForReaderCompletionAsync(this PipeWriter writer)
        {
            Requires.NotNull(writer, nameof(writer));

            var readerDone = new TaskCompletionSource <object>();

            writer.OnReaderCompleted(
                (ex, tcs) =>
            {
                if (ex != null)
                {
                    readerDone.SetException(ex);
                }
                else
                {
                    readerDone.SetResult(null);
                }
            },
                null);
            return(readerDone.Task);
        }
Пример #7
0
        public void Dispose()
        {
            lock (_contextLock)
            {
                if (_completed)
                {
                    return;
                }

                _log.ConnectionDisconnect(_connectionId);
                _completed = true;
                _pipeWriter.Complete();

                var unsentBytes = _totalBytesCommitted - _transportBytesWrittenFeature.TotalBytesWritten;

                if (unsentBytes > 0)
                {
                    // unsentBytes should never be over 64KB in the default configuration.
                    _timeoutControl.StartTimingWrite((int)Math.Min(unsentBytes, int.MaxValue));
                    _pipeWriter.OnReaderCompleted((ex, state) => ((ITimeoutControl)state).StopTimingWrite(), _timeoutControl);
                }
            }
        }
Пример #8
0
        internal static Task WaitForReaderCompletionAsync(this PipeWriter writer)
        {
            Requires.NotNull(writer, nameof(writer));

            var readerDone = new TaskCompletionSource <object?>();

#pragma warning disable CS0618 // Type or member is obsolete
            writer.OnReaderCompleted(
                (ex, tcsObject) =>
            {
                var tcs = (TaskCompletionSource <object?>)tcsObject;
                if (ex != null)
                {
                    tcs.SetException(ex);
                }
                else
                {
                    tcs.SetResult(null);
                }
            },
                readerDone);
#pragma warning restore CS0618 // Type or member is obsolete
            return(readerDone.Task);
        }
Пример #9
0
            // note - consider deprecated: https://github.com/dotnet/corefx/issues/38362
            public override void OnReaderCompleted(Action <Exception, object> callback, object state)
            {
#pragma warning disable CS0618 // obsolete
                _writer.OnReaderCompleted(callback, state);
#pragma warning restore CS0618 // obsolete
            }
Пример #10
0
 public override void OnReaderCompleted(Action <Exception, object> callback, object state)
 => _writer.OnReaderCompleted(callback, state);
Пример #11
0
        private async void DoStartListening(object o)
        {
            PipeWriter        writer = null;
            CancellationToken ct;
            UdpClient         udpClient = null;
            Exception         exception = null;

            try
            {
                (writer, ct) = (ValueTuple <PipeWriter, CancellationToken>)o;
                writer.OnReaderCompleted((ex, oo) =>
                {
                    exception  = ex;
                    _listening = false;
                }, null);

                using (udpClient = new UdpClient(Port))
                {
                    _timer = new Timer(uc =>
                    {
                        if (!_listening || ct.IsCancellationRequested)
                        {
                            ((UdpClient)uc)?.Close();
                            _timer?.Dispose();
                        }
                    }, udpClient, 1000, 1000);

                    while (_listening && !ct.IsCancellationRequested)
                    {
                        var result = await udpClient.ReceiveAsync();

                        var buffer = result.Buffer;

                        if (buffer.Length == 0)
                        {
                            continue;
                        }

                        if (!PacketParser.ValidatePacketHeaderAndLength(buffer))
                        {
                            continue;
                        }


                        await writer.WriteAsync(buffer, _cts.Token);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occured while receiving data from network", ex);
                exception = ex;
            }
            finally
            {
                if (exception != null)
                {
                    Logger.Warn("Finished writing because reader completed with exception", exception);
                }

                _timer?.Dispose();
                writer?.Complete();
                udpClient?.Close();
                _listening = false;
            }

            OnStopListening?.Invoke(this, exception);
        }