示例#1
0
    public static Task MergeAsync <T>(
        IEnumerable <ChannelReader <T> > inputs,
        ChannelWriter <T> output,
        CancellationToken stoppingToken)
    {
        if (inputs is null)
        {
            throw new ArgumentNullException(nameof(inputs));
        }
        if (output is null)
        {
            throw new ArgumentNullException(nameof(output));
        }

        return(Task.Run(async() =>
        {
            try
            {
                await Task.WhenAll(inputs.Select(input => RedirectAsync(input, output, stoppingToken))
                                   .ToArray())
                .ConfigureAwait(false);

                output.Complete();
            }
            catch (Exception ex)
            {
                output.Complete(ex);
                throw;
            }
        },
                        stoppingToken));
    }
        /// <summary>
        /// Asynchronously writes all entries from the source to the channel.
        /// </summary>
        /// <typeparam name="T">The input type of the channel.</typeparam>
        /// <param name="target">The channel to write to.</param>
        /// <param name="source">The asynchronous source data to use.</param>
        /// <param name="complete">If true, will call .Complete() if all the results have successfully been written (or the source is emtpy).</param>
        /// <param name="deferredExecution">If true, calls await Task.Yield() before writing.</param>
        /// <param name="cancellationToken">An optional cancellation token.</param>
        /// <returns>A task containing the count of items written that completes when all the data has been written to the channel writer.
        /// The count should be ignored if the number of iterations could exceed the max value of long.</returns>
        public static async ValueTask <long> WriteAllAsync <T>(this ChannelWriter <T> target,
                                                               IAsyncEnumerable <T> source, bool complete = false, bool deferredExecution = false, CancellationToken cancellationToken = default)
        {
            if (target is null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (source is null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            Contract.EndContractBlock();

            await target
            .WaitToWriteAndThrowIfClosedAsync(ChannelClosedMessage, deferredExecution, cancellationToken)
            .ConfigureAwait(false);

            try
            {
                long count = 0;
                var  next  = new ValueTask();
                await foreach (var value in source)
                {
                    await next.ConfigureAwait(false);

                    count++;
                    next = target.WriteAsync(value, cancellationToken);
                }
                await next.ConfigureAwait(false);

                return(count);
            }
            catch (Exception ex)
            {
                if (complete)
                {
                    target.Complete(ex);
                    complete = false;
                }
                throw;
            }
            finally
            {
                if (complete)
                {
                    target.Complete();
                }
            }
        }
示例#3
0
        public void Close()
        {
            lock (_semaphore)
            {
                if (_closed || _socket == null)
                {
                    return;
                }
                else
                {
                    try
                    {
                        _channelWriter.Complete();
                        _writerTask?.GetAwaiter().GetResult();
                    }
                    catch
                    {
                        // ignore, we are closing anyway
                    }

                    try
                    {
                        _socket.Close();
                    }
                    catch
                    {
                        // ignore, we are closing anyway
                    }
                    finally
                    {
                        _closed = true;
                    }
                }
            }
        }
示例#4
0
        private async Task SortChunks(ChannelReader <List <T> > channelReader, ChannelWriter <List <T> > channelWriter)
        {
            try
            {
                int index = Interlocked.Increment(ref _concurrencyCounter);

                _logger.Info($"{index}. Started sorting phase...");

                var stopwatch = Stopwatch.StartNew();

                while (await channelReader.WaitToReadAsync().ConfigureAwait(false))
                {
                    if (channelReader.TryRead(out var chunk))
                    {
                        _logger.Debug($"{index}. Started sorting chunk ...");
                        chunk.Sort();
                        _logger.Debug($"{index}. Chunk was sorted in {stopwatch.Elapsed}");
                        stopwatch.Restart();
                        await channelWriter.WriteAsync(chunk).ConfigureAwait(false);
                    }
                }

                _logger.Info($"{index}. Sorting phase is completed.");
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error occured while sorting: ", ex);
                channelWriter.Complete(ex);
                throw;
            }
        }
示例#5
0
        private void ReadLines(string logPath, ChannelWriter <LogDatum> writer)
        {
            WriteMessage("Reading log file: {0}", logPath);

            var sw = Stopwatch.StartNew();

            int count = 0;

            using (var fs = File.Open(logPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
                using (var sr = new StreamReader(fs))
                {
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        count++;
                        if (line == String.Empty)
                        {
                            continue;
                        }
                        var logLine = new LogDatum(line, count);
                        writer.TryWrite(logLine);
                    }
                }

            writer.Complete(); // We won't do this if this is a live file that's still being written to (how do we tell? Do we need to know?)
            sw.Stop();

            WriteMessage($"Done reading log file. {count,10:N0} lines {sw.Elapsed} elapsed");
        }
示例#6
0
 public void Stop()
 {
     _queueConsumer.Stop();
     _inboundChannelWritter.Complete();
     _inboundQueueProcessor.Wait();
     _inboundChannelProcessor.Wait();
 }
        public async Task RunAsync(CancellationToken ct)
        {
            try
            {
                var rnd = new Random();

                while (!ct.IsCancellationRequested)
                {
                    ++_count;
                    string message = $"Message{_count}";
                    Console.WriteLine($"Producing {message}");

                    await _writer.WriteAsync(message, ct);

                    Console.WriteLine($"Produced {message}");

                    await Task.Delay(TimeSpan.FromMilliseconds(rnd.Next(500, 1000)), ct);
                }
            }
            catch (OperationCanceledException)
            {
                // Consider cancellation as normal exit
            }
            finally
            {
                Console.WriteLine("Producer marking writer complete");
                _writer.Complete();
            }
        }
        private static async Task RunAsync()
        {
            var manejadorZip      = new ManejadorZip();
            var manejadorImagenes = new ManejadorImagenes();
            IEnumerable <string> listaDeFotografias = manejadorImagenes.GetListadoFotografias();

            Channel <byte[]> m_channel = Channel.CreateUnbounded <byte[]>();

            ChannelReader <byte[]> reader = m_channel.Reader;
            await Task.Factory.StartNew(async() => {
                while (await reader.WaitToReadAsync())
                {
                    while (reader.TryRead(out byte[] miniatura))
                    {
                        await manejadorZip.AgregarAZipAsync(miniatura);
                    }
                }
            });

            ChannelWriter <byte[]> writer = m_channel.Writer;

            foreach (var foto in listaDeFotografias)
            {
                // Generar miniatura
                byte[] miniatura = await manejadorImagenes.GenerarMiniaturaAsync(foto);

                writer.TryWrite(miniatura);
            }
            writer.Complete();
        }
示例#9
0
        public void Close()
        {
            lock (_semaphore)
            {
                if (!_closed)
                {
                    try
                    {
                        _channelWriter.Complete();
                        _writerTask.GetAwaiter().GetResult();
                    }
                    catch (Exception)
                    {
                    }

                    try
                    {
                        _socket.Close();
                    }
                    catch (Exception)
                    {
                        // ignore, we are closing anyway
                    }
                    finally
                    {
                        _closed = true;
                    }
                }
            }
        }
示例#10
0
        private static async Task StartMessagePumpAsync(Client client, ChannelWriter <bool> startSyncChannel, CancellationToken cancellationToken)
        {
            using var heartbeatTickerTicker = new TimerTicker(HeartbeatInterval);
            var heartbeatChannel = heartbeatTickerTicker.GetChannel(() => new Tick(), cancellationToken);

            startSyncChannel.Complete();

            var channels = new[] { heartbeatChannel, };

            while (!cancellationToken.IsCancellationRequested)
            {
                await foreach (var msg in ChannelExtension.Merge(channels, cancellationToken).ReadAllAsync(cancellationToken))
                {
                    switch (msg)
                    {
                    case Tick:
                        client.WriteMessage("heartbeat", HeartbeatInterval);
                        continue;

                    default:
                        throw new NotSupportedException();
                    }
                }
            }
        }
示例#11
0
    void Test()
    {
        Channel <int> queue = Channel.CreateBounded <int>(10);

        // Producer code
        ChannelWriter <int> writer = queue.Writer;

        Task.Run(async() =>
        {
            await writer.WriteAsync(7);
            await writer.WriteAsync(13);
            writer.Complete();
        }).GetAwaiter().GetResult();

        // Consumer code
        ChannelReader <int> reader = queue.Reader;

        Task.Run(async() =>
        {
            while (await reader.WaitToReadAsync())
            {
                while (reader.TryRead(out int value))
                {
                    Trace.WriteLine(value);
                }
            }
        }).GetAwaiter().GetResult();
    }
示例#12
0
        private async Task MapLeavesToIdsAsync(
            ChannelReader <CatalogLeafItem> leafChannel,
            ChannelWriter <string> packageIdChannel,
            CancellationToken cancellationToken)
        {
            var seen = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            while (await leafChannel.WaitToReadAsync(cancellationToken))
            {
                while (leafChannel.TryRead(out var leaf))
                {
                    // Skip package IDs that have already been seen.
                    if (!seen.Add(leaf.PackageId))
                    {
                        continue;
                    }

                    if (!packageIdChannel.TryWrite(leaf.PackageId))
                    {
                        await packageIdChannel.WriteAsync(leaf.PackageId);
                    }
                }
            }

            packageIdChannel.Complete();
        }
示例#13
0
        private async Task WriteItemsAsync(
            ChannelWriter <int> writer,
            int count,
            int delay)
        {
            Exception localException = null;

            try
            {
                for (var i = 0; i < count; i++)
                {
                    await writer.WriteAsync(i);

                    await Task.Delay(delay);
                }
            }
            catch (Exception ex)
            {
                localException = ex;
            }
            finally
            {
                writer.Complete(localException);
            }
        }
示例#14
0
        private async Task ReceiveMessagesAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    var message = await ReceiveMessageAsync(cancellationToken);

                    _log.LogTrace($"Enqueue {message}");
                    await _writer.WriteAsync(message, cancellationToken);
                }
                catch (TaskCanceledException ex)
                {
                    _log.LogDebug(ex.Message);
                }
                catch (Exception ex)
                {
                    _log.LogError(ex, ex.Message);
                }
            }

            _writer.Complete();

            _log.LogInformation($"Stopped receiving messages.");
        }
示例#15
0
        /// <summary>
        /// Asynchronously writes all entries from the source to the channel.
        /// </summary>
        /// <typeparam name="T">The input type of the channel.</typeparam>
        /// <param name="target">The channel to write to.</param>
        /// <param name="source">The asynchronous source data to use.</param>
        /// <param name="complete">If true, will call .Complete() if all the results have successfully been written (or the source is emtpy).</param>
        /// <param name="cancellationToken">An optional cancellation token.</param>
        /// <returns>A task containing the count of items written that completes when all the data has been written to the channel writer.
        /// The count should be ignored if the number of iterations could exceed the max value of long.</returns>
        public static async ValueTask <long> WriteAllAsync <T>(this ChannelWriter <T> target,
                                                               IEnumerable <ValueTask <T> > source, bool complete = false, CancellationToken cancellationToken = default)
        {
            await target.WaitToWriteAndThrowIfClosedAsync(
                "The target channel was closed before writing could begin.",
                cancellationToken);

            long count = 0;
            var  next  = new ValueTask();

            foreach (var e in source)
            {
                var value = await e.ConfigureAwait(false);

                await next.ConfigureAwait(false);

                count++;
                next = target.WriteAsync(value, cancellationToken);
            }
            await next.ConfigureAwait(false);

            if (complete)
            {
                target.Complete();
            }

            return(count);
        }
示例#16
0
        private void FetchPagesInParallel(int pageCount, ChannelWriter <IEnumerable <Person> > channelWriter, CancellationToken ct)
        {
            Task[] tasks = new Task[pageCount];
            for (int page = 0; page < pageCount; ++page)
            {
                int localPage = page;
                tasks[page] = _repo.GetPersonPage(page, _pageSize, ct)
                              .ContinueWith(task =>
                {
                    if (task.IsCompletedSuccessfully)
                    {
                        Console.WriteLine("Page {0} fetched successfully.", localPage);
                        channelWriter.TryWrite(task.Result);
                    }
                    else
                    {
                        Console.WriteLine("Fetching page {0} failed: {1}.", localPage, task.Exception);
                    }
                }, ct);
            }
            Task.WaitAll(tasks, ct);

            // complete the channel so that the reader stops after reading all data
            channelWriter.Complete();
        }
示例#17
0
        private async ValueTask StartReadPipe(PipeReader pipeReader, CancellationToken cancellationToken)
        {
            var processor = new PacketsProcessor(_channelWriter);

            try
            {
                while (true)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var result = await pipeReader.ReadAsync(cancellationToken);

                    var length = await processor.ProcessBytesAsync(result.Buffer, cancellationToken);

                    pipeReader.AdvanceTo(result.Buffer.GetPosition(length));
                    if (result.IsCompleted)
                    {
                        break;
                    }
                }
            }
            catch (SocketException e)
            {
                await pipeReader.CompleteAsync(e);

                _channelWriter.Complete(e);
            }
        }
示例#18
0
        private async Task ReadLines(string logPath, ChannelWriter <LogDatum> writer)
        {
            WriteMessage($"Starting channel reader - ReadLines");

            _sw.Start();

            int totalCount = 0;

            using (var fs = LogFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
                using (var sr = new StreamReader(fs))
                {
                    // This sets up our infinite loop of reading the file for new changes (until cancelled)
                    while (!CancelSource.IsCancellationRequested)
                    {
                        var count = ReadCurrentSetOfFileLines(sr, writer);
                        // var count = await ReadCurrentSetOfFileLinesAsync(sr, writer);
                        totalCount += count;

                        try
                        {
                            // Console.Write(".");
                            await Task.Delay(500, CancelSource.Token); // Ensures early exit if cancelled
                        }
                        catch (Exception ex) when(ex is ChannelClosedException || ex is OperationCanceledException || ex is TaskCanceledException)
                        {
                            WriteMessage($"ERROR: ReadLines - {ex.Message}, {ex.GetType()}");
                        }
                    }
                }
            WriteMessage($"Total Lines read: {totalCount:N0}");

            // We've been cancelled at this point, close out the channel
            writer.Complete();
            WriteMessage($"Finished channel reader - ReadLines");
        }
示例#19
0
        public async Task SplitAsync(long maxSize, CancellationToken token)
        {
            var partSize = 0L;

            var    lines = new List <string>();
            string line;

            using var reader = new StreamReader(_fileName);
            while ((line = await reader.ReadLineAsync()) != null)
            {
                partSize += line.Length * sizeof(char);

                if (partSize >= maxSize)
                {
                    await _fileWriter.WriteAsync(new ListPart(lines.ToArray()), token);

                    partSize = 0;
                    lines.Clear();
                }

                lines.Add(line);
            }

            if (partSize < maxSize)
            {
                await _fileWriter.WriteAsync(new ListPart(lines.ToArray()), token);
            }

            _fileWriter.Complete();
        }
 public void Close()
 {
     if (IsAlive())
     {
         writer.Complete();
     }
 }
示例#21
0
        private async Task WriteItemsAsync(
            ChannelWriter <int> writer,
            int count,
            int delay,
            CancellationToken cancellationToken)
        {
            Exception localException = null;

            try
            {
                for (var i = 0; i < count; i++)
                {
                    await writer.WriteAsync(i, cancellationToken);

                    // Use the cancellationToken in other APIs that accept cancellation
                    // tokens so the cancellation can flow down to them.
                    await Task.Delay(delay, cancellationToken);
                }
            }
            catch (Exception ex)
            {
                localException = ex;
            }

            writer.Complete(localException);
        }
示例#22
0
            async Task StreamingWriter(ChannelWriter <IDictionary <string, object> > writer, IDictionary <string, object> sentData, int count, int streamItemWaiting)
            {
                Exception localException = null;

                try
                {
                    for (var i = 0; i < count; i++)
                    {
                        sentData[SignalRConstants.Timestamp] = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();
                        await writer.WriteAsync(sentData);

                        if (streamItemWaiting > 0)
                        {
                            await Task.Delay(streamItemWaiting);
                        }
                        // Update statistics
                        SignalRUtils.RecordSend(sentData, StatisticsCollector);
                    }
                }
                catch (Exception ex)
                {
                    localException = ex;
                }
                writer.Complete(localException);
            }
示例#23
0
 private async Task OutboundMessageProcessor()
 {
     try
     {
         while (await _outboundChannelReader.WaitToReadAsync())
         {
             while (_outboundChannelReader.TryRead(out byte[] data))
             {
                 try
                 {
                     _outboundQueueChannelWritter.TryWrite(data);
                     _outboundFileChannelWritter.TryWrite(data);
                 }
                 catch (Exception ex)
                 {
                     Console.WriteLine(ex);
                     //TODO
                     throw;
                 }
             }
         }
         _outboundQueueChannelWritter.Complete();
         _outboundFileChannelWritter.Complete();
     }
     catch (Exception ex)
     {
         Console.WriteLine(ex);
         //TODO
         throw;
     }
 }
示例#24
0
        private async Task WriteStreamItemsAsync(
            string id,
            ChannelWriter <string> writer,
            int delay,
            CancellationToken cancellationToken)
        {
            var input = _hubBuffer.BufferChannel[id];

            Console.WriteLine($"Process the incoming stream from {id}");
            Exception localException = null;

            try
            {
                while (await input.WaitToReadAsync())
                {
                    while (input.TryRead(out var item))
                    {
                        Console.WriteLine(item);
                        await writer.WriteAsync(item);

                        await Task.Delay(delay);
                    }
                }
            }
            catch (Exception ex)
            {
                localException = ex;
            }
            writer.Complete(localException);
        }
示例#25
0
        private async Task WriteItemsAsync(
            ChannelWriter <int> writer,
            int count,
            int delay,
            CancellationToken cancellationToken)
        {
            Exception localException = null;

            try
            {
                for (var i = 0; i < count; i++)
                {
                    // Check the cancellation token regularly so that the server will stop
                    // producing items if the client disconnects.
                    cancellationToken.ThrowIfCancellationRequested();
                    await writer.WriteAsync(i);

                    // Use the cancellationToken in other APIs that accept cancellation
                    // tokens so the cancellation can flow down to them.
                    await Task.Delay(delay, cancellationToken);
                }
            }
            catch (Exception ex)
            {
                localException = ex;
            }
            finally
            {
                writer.Complete(localException);
            }
        }
        private async void SortLines(ChannelReader <ILine> reader, ChannelWriter <ILine> writer)
        {
            var lines = new Dictionary <int, ILine>();

            while (await reader.WaitToReadAsync())
            {
                while (reader.TryRead(out var line))
                {
                    if (_parserCount == 1)
                    {
                        writer.TryWrite(line);
                    }
                    else
                    {
                        lines.Add(line.LogLine.LineNumber, line);

                        if (lines.Count >= SortBatchSize * 2)
                        {
                            SortBatch(lines, writer);
                        }
                    }
                }
            }

            // Do the remainder of the lines
            if (_parserCount != 1)
            {
                SortBatch(lines, writer, true);
            }

            writer.Complete();
        }
        static async ChannelReader <string> Stage1(ChannelWriter <string> ch)
        {
            await ch.WriteAsync("Stage 1 - message 1");

            await ch.WriteAsync("Stage 1 - message 2");

            ch.Complete();
        }
示例#28
0
        private async Task ReadChunks(IEnumerable <T> source, ChannelWriter <List <T> > channelWriter)
        {
            try
            {
                _logger.Info("Starting reading phase...");

                var stopwatch      = Stopwatch.StartNew();
                var chunkStopwatch = Stopwatch.StartNew();

                var  currentChunk       = new List <T>();
                long currentChunkSize   = 0;
                long currentChunkNumber = 0;

                foreach (var value in source)
                {
                    currentChunk.Add(value);
                    if (currentChunkSize < _chunkSize)
                    {
                        currentChunkSize++;
                    }
                    else
                    {
                        _logger.Debug($"Chunk {currentChunkNumber} with {currentChunk.Count} lines was readen in {chunkStopwatch.Elapsed}.");
                        chunkStopwatch.Restart();
                        await channelWriter.WriteAsync(currentChunk).ConfigureAwait(false);

                        currentChunk     = new List <T>();
                        currentChunkSize = 0;
                        currentChunkNumber++;
                    }
                }

                _logger.Debug($"Chunk {currentChunkNumber} with {currentChunk.Count} lines was readen in {chunkStopwatch.Elapsed}.");
                await channelWriter.WriteAsync(currentChunk).ConfigureAwait(false);

                channelWriter.Complete();
                stopwatch.Stop();
                _logger.Info($"Reading phase is completed in {stopwatch.Elapsed}.");
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error occured while reading: ", ex);
                channelWriter.Complete(ex);
                throw;
            }
        }
 public void SetCommand(string command)
 {
     _inputWriter.WriteAsync(command);
     if (command == "exit")
     {
         _inputWriter.Complete();
     }
 }
示例#30
0
        private static async Task ReadFromClient(Socket socket, ChannelWriter <double> channel, int bufferSize)
        {
            var endPoint = socket.RemoteEndPoint; // save remote end point for logging

            Logger.Trace("read from client {} started", endPoint);

            using (var stream = new NetworkStream(socket))
            {
                var buffer  = new byte[bufferSize];
                var current = new List <byte>();
                while (true)
                {
                    var readCount = await stream.ReadAsync(buffer);

                    if (readCount == 0)
                    {
                        break;
                    }

                    var newLineIndex = Array.IndexOf(buffer, (byte)'\n', 0, readCount);
                    if (newLineIndex == -1)
                    {
                        // not find new line
                        current.AddRange(buffer.Take(readCount));
                        Logger.Trace("get {} bytes unfinished data from client {}", readCount, socket.RemoteEndPoint);
                    }
                    else
                    {
                        // find new line
                        current.AddRange(buffer.Take(newLineIndex));
                        var stringData = Encoding.UTF8.GetString(current.ToArray());
                        Logger.Trace("get string with length {} from client {}: {}",
                                     stringData.Length,
                                     socket.RemoteEndPoint,
                                     stringData);
                        current.Clear();
                        if (readCount > newLineIndex + 1)
                        {
                            // more data in this read
                            current.AddRange(buffer.Take(readCount).Skip(newLineIndex + 1)); // skip '\n'
                            Logger.Trace("get {} bytes unfinished data from client {}",
                                         readCount - newLineIndex - 1,
                                         socket.RemoteEndPoint);
                        }

                        if (!double.TryParse(stringData, out var result))
                        {
                            result = double.NaN;
                        }
                        await channel.WriteAsync(result);
                    }
                }

                channel.Complete();
            }

            Logger.Trace("end read from client {}", endPoint);
        }