public void FlushAsyncAwaitableCompletesWhenReaderAdvancesUnderLow()
        {
            PipeWriter writableBuffer          = _pipe.Writer.WriteEmpty(PauseWriterThreshold);
            ValueTask <FlushResult> flushAsync = writableBuffer.FlushAsync();

            Assert.False(flushAsync.IsCompleted);

            ReadResult       result   = _pipe.Reader.ReadAsync().GetAwaiter().GetResult();
            SequencePosition consumed = result.Buffer.GetPosition(33);

            _pipe.Reader.AdvanceTo(consumed, consumed);

            Assert.True(flushAsync.IsCompleted);
            FlushResult flushResult = flushAsync.GetAwaiter().GetResult();

            Assert.False(flushResult.IsCompleted);
        }
Esempio n. 2
0
        //写入循环
        private async Task FillPipeAsync(Socket socket, PipeWriter writer)
        {
            //数据流量比较大,用8k作为buffer
            const int minimumBufferSize = 1024 * 8;

            while (running)
            {
                try
                {
                    //从writer中,获得一段不少于指定大小的内存空间
                    Memory <byte> memory = writer.GetMemory(minimumBufferSize);
                    await socket.ReceiveAsync(memory, SocketFlags.None);

                    //将内存空间变成ArraySegment,提供给socket使用
                    if (!MemoryMarshal.TryGetArray((ReadOnlyMemory <byte>)memory, out ArraySegment <byte> arraySegment))
                    {
                        throw new InvalidOperationException("Buffer backed by array was expected");
                    }
                    //接受数据
                    int bytesRead = await SocketTaskExtensions.ReceiveAsync(socket, arraySegment, SocketFlags.None);

                    if (bytesRead == 0)
                    {
                        break;
                    }

                    //一次接受完毕,数据已经在pipe中,告诉pipe已经给它写了多少数据。
                    writer.Advance(bytesRead);
                }
                catch
                {
                    break;
                }

                // 提示reader可以进行读取数据,reader可以继续执行readAsync()方法
                FlushResult result = await writer.FlushAsync();

                if (result.IsCompleted)
                {
                    break;
                }
            }

            // 告诉pipe完事了
            writer.Complete();
        }
        public async Task WriteLargeDataBinary(int length)
        {
            var data = new byte[length];

            new Random(length).NextBytes(data);
            PipeWriter output = Pipe.Writer;

            output.Write(data);
            await output.FlushAsync();

            ReadResult result = await Pipe.Reader.ReadAsync();

            ReadOnlySequence <byte> input = result.Buffer;

            Assert.Equal(data, input.ToArray());
            Pipe.Reader.AdvanceTo(input.End);
        }
        public void FlushAsyncReturnsIsCancelOnCancelPendingFlushBeforeGetResult()
        {
            PipeWriter writableBuffer           = Pipe.Writer.WriteEmpty(MaximumSizeHigh);
            PipeAwaiter <FlushResult> awaitable = writableBuffer.FlushAsync();

            Assert.False(awaitable.IsCompleted);
            awaitable.OnCompleted(() => { });

            Pipe.Reader.AdvanceTo(Pipe.Reader.ReadAsync().GetResult().Buffer.End);
            Pipe.Writer.CancelPendingFlush();

            Assert.True(awaitable.IsCompleted);

            FlushResult result = awaitable.GetResult();

            Assert.True(result.IsCanceled);
        }
        public async Task DataWrittenOnFlushAsync()
        {
            byte[]     bytes  = Encoding.ASCII.GetBytes("Hello World");
            var        stream = new MemoryStream();
            PipeWriter writer = PipeWriter.Create(stream);

            bytes.AsSpan().CopyTo(writer.GetSpan(bytes.Length));
            writer.Advance(bytes.Length);
            await writer.FlushAsync();

            Assert.Equal(bytes.Length, stream.Length);
            Assert.Equal("Hello World", Encoding.ASCII.GetString(stream.ToArray()));

            writer.Complete();

            Assert.Equal(0, writer.UnflushedBytes);
        }
        private static ValueTask <bool> Flush(PipeWriter writer)
        {
            bool GetResult(FlushResult flush)
            // tell the calling code whether any more messages
            // should be written
            => !(flush.IsCanceled || flush.IsCompleted);

            async ValueTask <bool> Awaited(ValueTask <FlushResult> incomplete)
            => GetResult(await incomplete);

            // apply back-pressure etc
            var flushTask = writer.FlushAsync();

            return(flushTask.IsCompletedSuccessfully
                ? new ValueTask <bool>(GetResult(flushTask.Result))
                : Awaited(flushTask));
        }
Esempio n. 7
0
        public async ValueTask Add(byte[] e)
        {
            void Write()
            {
                var span = _writer.GetSpan(e.Length);

                for (var i = 0; i < e.Length; i++)
                {
                    span[i] = e[i];
                }

                _writer.Advance(e.Length);
            }

            Write();
            await _writer.FlushAsync();
        }
Esempio n. 8
0
        public async Task ReadAsync()
        {
            PipeWriter writer = _pipe.Writer;
            PipeReader reader = _pipe.Reader;

            for (int i = 0; i < InnerIterationCount; i++)
            {
                ValueTask <ReadResult> task = reader.ReadAsync();

                await writer.WriteAsync(_data);

                await writer.FlushAsync();

                ReadResult result = await task;
                reader.AdvanceTo(result.Buffer.End);
            }
        }
Esempio n. 9
0
        public async Task DefaultReaderSchedulerIgnoresSyncContextIfConfigureAwaitFalse()
        {
            // Get off the xunit sync context

            var previous = SynchronizationContext.Current;

            try
            {
                var sc = new CustomSynchronizationContext();
                SynchronizationContext.SetSynchronizationContext(sc);

                var pipe = new Pipe();

                Func <Task> doRead = async() =>
                {
                    ReadResult result = await pipe.Reader.ReadAsync().ConfigureAwait(false);

                    Assert.True(Thread.CurrentThread.IsThreadPoolThread);

                    pipe.Reader.AdvanceTo(result.Buffer.End, result.Buffer.End);

                    pipe.Reader.Complete();
                };

                // This needs to run on the current SynchronizationContext
                Task reading = doRead();

                PipeWriter buffer = pipe.Writer;
                buffer.Write(Encoding.UTF8.GetBytes("Hello World"));

                // We don't want to run any code on our fake sync context
                await buffer.FlushAsync().ConfigureAwait(false);

                // Nothing posted to the sync context
                Assert.Equal(0, sc.Callbacks.Count);

                pipe.Writer.Complete();

                // We don't want to run any code on our fake sync context
                await reading.ConfigureAwait(false);
            }
            finally
            {
                SynchronizationContext.SetSynchronizationContext(previous);
            }
        }
Esempio n. 10
0
        public async Task FlushCallbackRunsOnWriterScheduler()
        {
            using (var pool = new TestMemoryPool())
            {
                using (var scheduler = new ThreadScheduler())
                {
                    var pipe = new Pipe(
                        new PipeOptions(
                            pool,
                            resumeWriterThreshold: 32,
                            pauseWriterThreshold: 64,
                            readerScheduler: PipeScheduler.Inline,
                            writerScheduler: scheduler,
                            useSynchronizationContext: false));

                    PipeWriter writableBuffer          = pipe.Writer.WriteEmpty(64);
                    ValueTask <FlushResult> flushAsync = writableBuffer.FlushAsync();

                    Assert.False(flushAsync.IsCompleted);

                    Func <Task> doWrite = async() =>
                    {
                        int oid = Thread.CurrentThread.ManagedThreadId;

                        await flushAsync;

                        Assert.NotEqual(oid, Thread.CurrentThread.ManagedThreadId);

                        pipe.Writer.Complete();

                        Assert.Equal(Thread.CurrentThread.ManagedThreadId, scheduler.Thread.ManagedThreadId);
                    };

                    Task writing = doWrite();

                    ReadResult result = await pipe.Reader.ReadAsync();

                    pipe.Reader.AdvanceTo(result.Buffer.End, result.Buffer.End);

                    pipe.Reader.Complete();

                    await writing;
                }
            }
        }
        private async Task FillPipeAsync(JT1078TcpSession session, PipeWriter writer)
        {
            while (true)
            {
                try
                {
                    Memory <byte> memory = writer.GetMemory(Configuration.MiniNumBufferSize);
                    //设备多久没发数据就断开连接 Receive Timeout.
                    int bytesRead = await session.Client.ReceiveAsync(memory, SocketFlags.None, session.ReceiveTimeout.Token);

                    if (bytesRead == 0)
                    {
                        break;
                    }
                    writer.Advance(bytesRead);
                }
                catch (System.ObjectDisposedException ex)
                {
                }
                catch (OperationCanceledException ex)
                {
                    Logger.LogError($"[Receive Timeout]:{session.Client.RemoteEndPoint}");
                    break;
                }
                catch (System.Net.Sockets.SocketException ex)
                {
                    Logger.LogError($"[{ex.SocketErrorCode.ToString()},{ex.Message}]:{session.Client.RemoteEndPoint}");
                    break;
                }
#pragma warning disable CA1031 // Do not catch general exception types
                catch (Exception ex)
                {
                    Logger.LogError(ex, $"[Receive Error]:{session.Client.RemoteEndPoint}");
                    break;
                }
#pragma warning restore CA1031 // Do not catch general exception types
                FlushResult result = await writer.FlushAsync();

                if (result.IsCompleted)
                {
                    break;
                }
            }
            writer.Complete();
        }
Esempio n. 12
0
        public async Task CompleteAsyncDoesNotThrowObjectDisposedException()
        {
            byte[]     bytes  = Encoding.ASCII.GetBytes("Hello World");
            var        stream = new MemoryStream();
            PipeWriter writer = PipeWriter.Create(stream, new StreamPipeWriterOptions(leaveOpen: true));

            await writer.FlushAsync();

            bytes.AsSpan().CopyTo(writer.GetSpan(bytes.Length));
            writer.Advance(bytes.Length);

            Assert.Equal(0, stream.Length);

            await writer.CompleteAsync();

            Assert.Equal(bytes.Length, stream.Length);
            Assert.Equal("Hello World", Encoding.ASCII.GetString(stream.ToArray()));
        }
Esempio n. 13
0
 private async Task WriteLoop(PipeWriter writer, CancellationToken cancellationToken)
 {
     try
     {
         while (await _listener.Messages.WaitToReadAsync(cancellationToken))
         {
             while (!cancellationToken.IsCancellationRequested && _listener.Messages.TryRead(out var message))
             {
                 EventPipeProtocol.WriteMessage(message, writer);
             }
             await writer.FlushAsync();
         }
     }
     catch (OperationCanceledException)
     {
         // No-op, we're just shutting down.
     }
 }
        public async Task WritesUsingGetMemoryWorks()
        {
            var        bytes   = Encoding.ASCII.GetBytes("abcdefghijklmnopqrstuvwzyz");
            var        stream  = new MemoryStream();
            var        options = new StreamPipeWriterOptions(new HeapBufferPool(), minimumBufferSize: 1);
            PipeWriter writer  = PipeWriter.Create(stream, options);

            for (int i = 0; i < bytes.Length; i++)
            {
                writer.GetMemory().Span[0] = bytes[i];
                writer.Advance(1);
            }

            await writer.FlushAsync();

            Assert.Equal(bytes, stream.ToArray());
            writer.Complete();
        }
Esempio n. 15
0
        public async Task WriteAndCancellingPendingReadBeforeReadAtLeastAsync()
        {
            byte[]     bytes  = "Hello World" u8.ToArray();
            PipeWriter output = Pipe.Writer;

            output.Write(bytes);
            await output.FlushAsync();

            PipeReader.CancelPendingRead();

            ReadResult result = await PipeReader.ReadAtLeastAsync(1000);

            ReadOnlySequence <byte> buffer = result.Buffer;

            Assert.False(result.IsCompleted);
            Assert.True(result.IsCanceled);
            PipeReader.AdvanceTo(buffer.End);
        }
Esempio n. 16
0
        public async Task AcceptPipeWriter(PipeWriter writer, int lengthToWrite, CancellationToken cancellationToken)
        {
            const int ChunkSize    = 5;
            int       writtenBytes = 0;

            while (writtenBytes < lengthToWrite)
            {
                // Write in small chunks to verify that it needn't be written all at once.
                int bytesToWrite = Math.Min(lengthToWrite - writtenBytes, ChunkSize);
                await writer.WriteAsync(MemoryBuffer.AsMemory(writtenBytes, bytesToWrite), cancellationToken);

                await writer.FlushAsync(cancellationToken);

                writtenBytes += bytesToWrite;
            }

            writer.Complete();
        }
Esempio n. 17
0
        public async Task FillPipeAsync(Stream sourceStream, PipeWriter writer, CancellationToken cancellationToken)
        {
            try
            {
                using (var fileStream = new FileStream(Path.GetTempFileName(), FileMode.Create, FileAccess.ReadWrite, FileShare.Read, 16384, FileOptions.Asynchronous | FileOptions.RandomAccess | FileOptions.DeleteOnClose))
                {
                    await sourceStream.CopyToAsync(fileStream, 16384, cancellationToken).ConfigureAwait(false);

                    fileStream.Seek(0, SeekOrigin.Begin);
                    using (var zipArchive = SevenZipArchive.Open(fileStream))
                        using (var zipReader = zipArchive.ExtractAllEntries())
                            while (zipReader.MoveToNextEntry())
                            {
                                if (!zipReader.Entry.IsDirectory &&
                                    zipReader.Entry.Key.EndsWith(".log", StringComparison.InvariantCultureIgnoreCase) &&
                                    !zipReader.Entry.Key.Contains("tty.log", StringComparison.InvariantCultureIgnoreCase))
                                {
                                    LogSize = zipReader.Entry.Size;
                                    using (var entryStream = zipReader.OpenEntryStream())
                                    {
                                        int         read;
                                        FlushResult flushed;
                                        do
                                        {
                                            var memory = writer.GetMemory(Config.MinimumBufferSize);
                                            read = await entryStream.ReadAsync(memory, cancellationToken);

                                            writer.Advance(read);
                                            flushed = await writer.FlushAsync(cancellationToken).ConfigureAwait(false);
                                        } while (read > 0 && !(flushed.IsCompleted || flushed.IsCanceled || cancellationToken.IsCancellationRequested));
                                    }
                                    writer.Complete();
                                    return;
                                }
                            }
                    Config.Log.Warn("No 7z entries that match the log criteria");
                }
            }
            catch (Exception e)
            {
                Config.Log.Error(e, "Error filling the log pipe");
            }
            writer.Complete();
        }
        /// <summary>
        /// Writes all the content of the Stream in the PipeWriter
        /// </summary>
        public static async ValueTask CopyToAsync(this Stream stream, PipeWriter writer, int bufferSize,
                                                  CancellationToken cancellationToken = default(CancellationToken))
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }
            if (bufferSize <= 0)
            {
                throw new ArgumentException("buffer size cannot be negative", nameof(bufferSize));
            }

            try
            {
                while (true)
                {
                    var buffer    = writer.GetMemory(bufferSize);
                    int bytesRead = await stream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false);

                    if (bytesRead == 0)
                    {
                        break;
                    }

                    writer.Advance(bytesRead);
                    var flush = await writer.FlushAsync(cancellationToken);

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

                writer.Complete();
            }
            catch (Exception err)
            {
                writer.Complete(err);
            }
        }
Esempio n. 19
0
    public async Task ReceiveAsync(
        PipeWriter writer,
        CancellationToken cancellationToken)
    {
        WebSocket?webSocket = _webSocket;

        if (_disposed || webSocket == null)
        {
            return;
        }

        try
        {
            ValueWebSocketReceiveResult socketResult;
            do
            {
                if (webSocket.State != WebSocketState.Open)
                {
                    break;
                }

                Memory <byte> memory = writer.GetMemory(_maxMessageSize);
                socketResult = await webSocket.ReceiveAsync(memory, cancellationToken);

                if (socketResult.Count == 0)
                {
                    break;
                }

                writer.Advance(socketResult.Count);

                FlushResult result = await writer.FlushAsync(cancellationToken);

                if (result.IsCompleted)
                {
                    break;
                }
            } while (!socketResult.EndOfMessage);
        }
        catch
        {
            // swallow exception, there's nothing we can reasonably do
        }
    }
        public async Task ThreadPoolScheduler_SchedulesOnThreadPool()
        {
            var pipe = new Pipe(new PipeOptions(readerScheduler: PipeScheduler.ThreadPool, writerScheduler: PipeScheduler.Inline, useSynchronizationContext: false));

            async Task DoRead()
            {
                // Make sure we aren't on a thread pool thread
                Assert.False(Thread.CurrentThread.IsThreadPoolThread, "We started on the thread pool");

                ValueTask <ReadResult> task = pipe.Reader.ReadAsync();

                Assert.False(task.IsCompleted, "Task completed synchronously");

                ReadResult result = await task;

                Assert.True(Thread.CurrentThread.IsThreadPoolThread);

                pipe.Reader.AdvanceTo(result.Buffer.End, result.Buffer.End);
                pipe.Reader.Complete();
            }

            bool callbackRan = false;

            // Wait start the thread and wait for it to finish
            Task reading = ExecuteOnNonThreadPoolThread(DoRead);

            PipeWriter buffer = pipe.Writer;

#pragma warning disable CS0618 // Type or member is obsolete
            pipe.Writer.OnReaderCompleted((state, exception) =>
            {
                callbackRan = true;
                Assert.True(Thread.CurrentThread.IsThreadPoolThread);
            },
                                          null);
#pragma warning restore CS0618 // Type or member is obsolete

            buffer.Write(Encoding.UTF8.GetBytes("Hello World"));
            await buffer.FlushAsync();

            await reading;

            Assert.True(callbackRan);
        }
        private async Task Receive(WebSocket webSocket, PipeWriter writer)
        {
            const int minimumBufferSize = 1024;

            while (true)
            {
                try
                {
                    Memory <byte>          memory = writer.GetMemory(minimumBufferSize);
                    WebSocketReceiveResult result = await webSocket.ReceiveAsync(memory);

                    if (result.Count == 0)
                    {
                        break;
                    }
                    // Tell the PipeWriter how much was read
                    writer.Advance(result.Count);
                    switch (result.MessageType)
                    {
                    case WebSocketMessageType.Close:
                        return;

                    case WebSocketMessageType.Text:
                    case WebSocketMessageType.Binary:
                        string value = Encoding.UTF8.GetString(memory.ToArray(), 0, result.Count);
                        Console.WriteLine(value);
                        break;
                    }
                }
                catch
                {
                    break;
                }
                // Make the data available to the PipeReader
                FlushResult flushResult = await writer.FlushAsync();

                if (flushResult.IsCompleted)
                {
                    break;
                }
            }
            // Signal to the reader that we're done writing
            writer.Complete();
        }
Esempio n. 22
0
        public static async Task WriteMessageAsync <TResponse>(this PipeWriter pipeWriter, TResponse response, HttpContextServerCallContext serverCallContext, Action <TResponse, SerializationContext> serializer, bool canFlush)
            where TResponse : class
        {
            var logger = serverCallContext.Logger;

            try
            {
                // Must call StartAsync before the first pipeWriter.GetSpan() in WriteHeader
                var httpResponse = serverCallContext.HttpContext.Response;
                if (!httpResponse.HasStarted)
                {
                    await httpResponse.StartAsync();
                }

                GrpcServerLog.SendingMessage(logger);

                var serializationContext = serverCallContext.SerializationContext;
                serializationContext.Reset();
                serializationContext.ResponseBufferWriter = pipeWriter;
                serializer(response, serializationContext);

                // Flush messages unless WriteOptions.Flags has BufferHint set
                var flush = canFlush && ((serverCallContext.WriteOptions?.Flags ?? default) & WriteFlags.BufferHint) != WriteFlags.BufferHint;

                if (flush)
                {
                    serverCallContext.HasBufferedMessage = false;
                    await pipeWriter.FlushAsync();
                }
                else
                {
                    // Set flag so buffered message will be written at the end
                    serverCallContext.HasBufferedMessage = true;
                }

                GrpcServerLog.MessageSent(serverCallContext.Logger);
                GrpcEventSource.Log.MessageSent();
            }
            catch (Exception ex)
            {
                GrpcServerLog.ErrorSendingMessage(logger, ex);
                throw;
            }
        }
Esempio n. 23
0
        /// <summary>
        /// Read all to writer
        /// 读取所有字节到写入器
        /// </summary>
        /// <param name="reader">Reader</param>
        /// <param name="writer">Pipe writer</param>
        /// <param name="encoding">Encoding</param>
        /// <returns>Task</returns>
        public static async Task ReadAllBytesAsyn(this TextReader reader, PipeWriter writer, Encoding?encoding = null)
        {
            // Default encoding
            encoding ??= Encoding.UTF8;

            // Memory for read
            Memory <char> memory = new char[BytesToRead];

            int read;

            while ((read = await reader.ReadBlockAsync(memory)) > 0)
            {
                // Write the chars to writer
                encoding.GetBytes(memory.Span.Slice(0, read), writer);

                // Make bytes written available
                await writer.FlushAsync();
            }
        }
Esempio n. 24
0
        private async Task FillPipe(CancellationToken cancellationToken)
        {
            await Task.Yield();

            try
            {
#if NETSTANDARD2_0
                var buffer = new byte[84999];
#endif
                while (true)
                {
                    var memory = _writer.GetMemory(84999);
#if NETSTANDARD2_0
                    var bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false);

                    new Memory <byte>(buffer, 0, bytesRead).CopyTo(memory);
#else
                    var bytesRead = await _stream.ReadAsync(memory, cancellationToken).ConfigureAwait(false);
#endif
                    if (bytesRead == 0)
                    {
                        break;
                    }

                    _writer.Advance(bytesRead);

                    var result = await _writer.FlushAsync(cancellationToken).ConfigureAwait(false);

                    if (result.IsCompleted)
                    {
                        break;
                    }
                }
            }
            catch
            {
                // ignored
            }
            finally
            {
                await _writer.CompleteAsync().ConfigureAwait(false);
            }
        }
Esempio n. 25
0
        public async Task UseSynchronizationContextFalseIgnoresSyncContextForReaderScheduler()
        {
            SynchronizationContext previous = SynchronizationContext.Current;
            var sc = new CustomSynchronizationContext();

            try
            {
                SynchronizationContext.SetSynchronizationContext(sc);

                var pipe = new Pipe(new PipeOptions(useSynchronizationContext: false));

                Func <Task> doRead = async() =>
                {
                    ReadResult result = await pipe.Reader.ReadAsync();

                    pipe.Reader.AdvanceTo(result.Buffer.End, result.Buffer.End);

                    pipe.Reader.Complete();
                };

                // This needs to run on the current SynchronizationContext
                Task reading = doRead();

                PipeWriter buffer = pipe.Writer;
                buffer.Write("Hello World" u8.ToArray());

                // Don't run code on our sync context (we just want to make sure the callbacks)
                // are scheduled on the sync context
                await buffer.FlushAsync().ConfigureAwait(false);

                // Nothing posted to the sync context
                Assert.Equal(0, sc.Callbacks.Count);

                pipe.Writer.Complete();

                // Don't run code on our sync context
                await reading.ConfigureAwait(false);
            }
            finally
            {
                SynchronizationContext.SetSynchronizationContext(previous);
            }
        }
Esempio n. 26
0
        public async Task HelloWorldAcrossTwoBlocks()
        {
            //     block 1       ->    block2
            // [padding..hello]  ->  [  world   ]
            PipeWriter writeBuffer = _pipe.Writer;
            var        blockSize   = _pipe.Writer.GetMemory().Length;

            byte[] paddingBytes = Enumerable.Repeat((byte)'a', blockSize - 5).ToArray();
            byte[] bytes        = Encoding.ASCII.GetBytes("Hello World");

            writeBuffer.Write(paddingBytes);
            writeBuffer.Write(bytes);
            await writeBuffer.FlushAsync();

            ReadResult result = await _pipe.Reader.ReadAsync();

            ReadOnlySequence <byte> buffer = result.Buffer;

            Assert.False(buffer.IsSingleSegment);
            ReadOnlySequence <byte> helloBuffer = buffer.Slice(blockSize - 5);

            Assert.False(helloBuffer.IsSingleSegment);
            var memory = new List <ReadOnlyMemory <byte> >();

            foreach (ReadOnlyMemory <byte> m in helloBuffer)
            {
                memory.Add(m);
            }

            List <ReadOnlyMemory <byte> > spans = memory;

            _pipe.Reader.AdvanceTo(buffer.Start, buffer.Start);

            Assert.Equal(2, memory.Count);
            var helloBytes = new byte[spans[0].Length];

            spans[0].Span.CopyTo(helloBytes);
            var worldBytes = new byte[spans[1].Length];

            spans[1].Span.CopyTo(worldBytes);
            Assert.Equal("Hello", Encoding.ASCII.GetString(helloBytes));
            Assert.Equal(" World", Encoding.ASCII.GetString(worldBytes));
        }
        public async Task DefaultReaderSchedulerRunsOnSynchronizationContext()
        {
            SynchronizationContext previous = SynchronizationContext.Current;
            var sc = new CustomSynchronizationContext();

            try
            {
                SynchronizationContext.SetSynchronizationContext(sc);

                var pipe = new Pipe();

                Func <Task> doRead = async() =>
                {
                    ReadResult result = await pipe.Reader.ReadAsync();

                    pipe.Reader.AdvanceTo(result.Buffer.End, result.Buffer.End);

                    pipe.Reader.Complete();
                };

                // This needs to run on the current SynchronizationContext
                Task reading = doRead();

                PipeWriter buffer = pipe.Writer;
                buffer.Write(Encoding.UTF8.GetBytes("Hello World"));

                // Don't run code on our sync context (we just want to make sure the callbacks)
                // are scheduled on the sync context
                await buffer.FlushAsync().ConfigureAwait(false);

                Assert.Equal(1, sc.Callbacks.Count);
                sc.Callbacks[0].Item1(sc.Callbacks[0].Item2);

                pipe.Writer.Complete();

                // Don't run code on our sync context
                await reading.ConfigureAwait(false);
            }
            finally
            {
                SynchronizationContext.SetSynchronizationContext(previous);
            }
        }
        public int EncodeBinaryMessage(PipeWriter writer, WebSocketMessage pack)
        {
            var head = writer.GetSpan(10);

            head[0] = (byte)((byte)pack.OpCode | 0x80);

            var headLen = WriteLength(ref head, pack.Data.Length);

            writer.Advance(headLen);

            foreach (var dataPiece in pack.Data)
            {
                writer.Write(dataPiece.Span);
                writer.Advance(dataPiece.Length);
            }

            writer.FlushAsync().GetAwaiter().GetResult();
            return((int)(pack.Data.Length + headLen));
        }
Esempio n. 29
0
        private async Task FillPipeAsync(PipeWriter writer, CancellationToken cancellationToken = default)
        {
            var ns = _tcpClient.GetStream();

            ns.ReadTimeout = 20 * 1000;

            while (!cancellationToken.IsCancellationRequested)
            {
                //var memory = writer.GetMemory(_buffer.Length);
                try
                {
                    var bytesRead = await ns.ReadAsync(_buffer, 0, _buffer.Length, cancellationToken);

                    if (bytesRead < 1)
                    {
                        break;
                    }

                    await writer.WriteAsync(new ReadOnlyMemory <byte>(_buffer, 0, bytesRead), cancellationToken);

                    //writer.Advance(bytesRead);
                }
                catch (ObjectDisposedException)
                {
                    // Normal dispose
                    break;
                }
                catch (Exception ex)
                {
                    OnError(ex, true);
                    break;
                }

                var result = await writer.FlushAsync(cancellationToken);

                if (result.IsCompleted)
                {
                    break;
                }
            }

            writer.Complete();
        }
Esempio n. 30
0
        private async Task PipeListener(Socket socket, PipeWriter writer)
        {
            const int bufferSize = 512;

            while (_client.Connected)
            {
                var memory = writer.GetMemory(bufferSize);
                try
                {
                    if (!socket.Connected)
                    {
                        await _client.Disconnect();

                        return;
                    }

                    int bytesRead;
                    try
                    {
                        bytesRead = await socket.ReceiveAsync(memory, SocketFlags.None);
                    }
                    catch (SocketException)
                    {
                        await _client.Disconnect();

                        break;
                    }
                    if (bytesRead == 0)
                    {
                        break;
                    }

                    writer.Advance(bytesRead);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    //
                }

                await writer.FlushAsync();
            }
        }