示例#1
0
 internal Task?CreateReader(PipelineBuildDefinition pipeline, Stream stream)
 {
     throw new NotImplementedException();
 }
示例#2
0
        internal async Task CreateReader(PipelineBuildDefinition def, ISegmenter segmenter)
        {
            var context = new
            {
                pipeline          = def.Pipe.Reader,
                onError           = def.OnReaderError ?? def.OnError,
                cancellationToken = def.CancellationTokenSource.Token,
                owner             = segmenter,
            };

            var completed = false;

            while (!context.cancellationToken.IsCancellationRequested)
            {
                var result = await context.pipeline.ReadAsync(context.cancellationToken);

                try
                {
                    var buffer = result.Buffer;

                    while (!context.cancellationToken.IsCancellationRequested)
                    {
                        var read = await segmenter.TryReadAsync(buffer);

                        buffer = read.RemainingData;
                        if (read.Status == SegmentationStatus.Incomplete)
                        {
                            break;
                        }
                        else if (read.Status == SegmentationStatus.Invalid)
                        {
                            throw new InvalidSegmentationException();
                        }
                    }

                    // Tell the PipeReader how much of the buffer we have consumed
                    context.pipeline.AdvanceTo(buffer.Start, buffer.End);
                }
                catch (Exception ex)
                {
                    var errorHandling = await context.onError.Handle(context.owner, ex);

                    switch (errorHandling)
                    {
                    case ErrorHandling.Ignore:
                        //Note: do nothing
                        break;

                    case ErrorHandling.Stop:
                        completed = true;
                        break;

                    default:
                    case ErrorHandling.Throw:
                        context.pipeline.Complete(ex);
                        return;
                    }
                }

                // Stop reading if there's no more data coming
                if (result.IsCompleted || completed)
                {
                    break;
                }
            }

            //Mark the PipeReader as complete
            context.pipeline.Complete();
        }
示例#3
0
        //https://devblogs.microsoft.com/dotnet/system-io-pipelines-high-performance-io-in-net/
        internal async Task CreateWriter(PipelineBuildDefinition def, Stream stream, int minimumBufferSize)
        {
            var context = new
            {
                pipeline          = def.Pipe.Writer,
                onError           = def.OnWriterError ?? def.OnError,
                cancellationToken = def.CancellationTokenSource.Token,
                owner             = stream,
            };

            var completed = false;

            while (!context.cancellationToken.IsCancellationRequested)
            {
                // Allocate at least 512 bytes from the PipeWriter
                var memory = context.pipeline.GetMemory(minimumBufferSize);
                try
                {
                    var read = await context.owner.ReadAsync(memory, context.cancellationToken);

                    if (read == 0)
                    {
                        break;
                    }

                    // Tell the PipeWriter how much was read from the Socket
                    context.pipeline.Advance(read);
                }
                catch (Exception ex)
                {
                    var errorHandling = await context.onError.Handle(context.owner, ex);

                    switch (errorHandling)
                    {
                    case ErrorHandling.Ignore:
                        //Note: do nothing
                        break;

                    case ErrorHandling.Stop:
                        completed = true;
                        break;

                    default:
                    case ErrorHandling.Throw:
                        context.pipeline.Complete(ex);
                        return;
                    }
                }

                // Make the data available to the PipeReader
                var result = await context.pipeline.FlushAsync();

                if (result.IsCompleted || completed)
                {
                    break;
                }
            }

            // Tell the PipeReader that there's no more data coming
            context.pipeline.Complete();
        }