コード例 #1
0
    async Task Test()
    {
        var _asyncStack = new AsyncCollection <int>(
            new ConcurrentStack <int>(), maxCount: 1);



        // This Add completes immediately.
        await _asyncStack.AddAsync(7);

        // This Add (asynchronously) waits for the 7 to be removed
        // before it enqueues the 13.
        await _asyncStack.AddAsync(13);

        _asyncStack.CompleteAdding();



        while (true)
        {
            int item;
            try
            {
                item = await _asyncStack.TakeAsync();
            }
            catch (InvalidOperationException)
            {
                break;
            }
            Trace.WriteLine(item);
        }
    }
コード例 #2
0

        
コード例 #3
0
        private async Task Producer()
        {
            await _asyncCollection.AddAsync(7);

            await _asyncCollection.AddAsync(13);

            _asyncCollection.CompleteAdding();
        }
コード例 #4
0
        async Task EnableReading()
        {
            try
            {
                while (true)
                {
                    var packet = await Stream.ReadMessageAsync(CancelSource.Token);

                    if (packet == null)
                    {
                        RemoteDisconnect();
                        return;
                    }

                    ReceivingStream.ReadMessage(packet);

                    while (ReceivingStream.HasMessage)
                    {
                        await ReceiveQueue.AddAsync(ReceivingStream.GetMessage());
                    }
                }
            }
            catch
            {
                RemoteDisconnect();
            }
        }
コード例 #5
0
        public async Task Process(CancellationToken cancellationToken)
        {
            while (true)
            {
                // The AsyncProducerConsumerQueue should never be in a completed state,
                // so DequeueAsync should only throw OperationCanceledException,
                // in which case the item should still be in the queue.
                var item = await input.TakeAsync(cancellationToken).ConfigureAwait(false);

                logger.ConditionalDebug("Processing \"{0}\"", item.Description);

                try
                {
                    await torrentClientStatus.WaitAsync().ConfigureAwait(false);
                    await AddItemAsync(item, cancellationToken).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    // Put the item back in the queue, so it is not lost.
                    // Do not provide a CancellationToken to try to ensure that the operation succeeds.
                    logger.Warn("Adding \"{0}\" back into the queue due to failure", item.Description);
                    await input.AddAsync(item).ConfigureAwait(false);

                    if (ex is OperationCanceledException)
                    {
                        throw;
                    }
                    else
                    {
                        logger.Error(ex, "Adding torrent failed");
                    }
                }
            }
        }
コード例 #6
0
        private static void StartProducer()
        {
            Task.Factory.StartNew(async() =>
            {
                var counter = 0;

                while (++counter <= 50)
                {
                    await asyncCollection.AddAsync(counter);
                    await asyncCollection.AddAsync(++counter);

                    Thread.Sleep(TimeSpan.FromSeconds(0.1));
                }

                asyncCollection.CompleteAdding();
            });
        }
コード例 #7
0
ファイル: BytesBuffer.cs プロジェクト: Nero0909/FileManager
        public async Task FillSegmentAsync(ArraySegment <byte> segment, int newSize, CancellationToken token)
        {
            if (segment.Count != newSize)
            {
                _offsetSize[segment.Offset] = newSize;
            }

            await _filledSegments.AddAsync(segment.Offset, token);
        }
コード例 #8
0
        async void Example14()
        {
            //限流
            AsyncCollection <int> _asyncStack = new AsyncCollection <int>(new ConcurrentStack <int>(), maxCount: 1);
            await _asyncStack.AddAsync(7);  //这个添加过程会立即完成。

            await _asyncStack.AddAsync(13); //这个添加(异步地)等待,直到7被移除,然后才会加入13。

            _asyncStack.CompleteAdding();

            //多个消费者
            while (true)
            {
                //var takeResult = await _asyncStack.TryTaskAsync();
                //if (!takeResult.Success) break;
                //Trace.WriteLine(takeResult.Item);
            }
        }
コード例 #9
0
 /// <summary>
 /// Checks if the command request is allowed and enqueues it internally if that is the case.
 /// If it is illegal, an exception is thrown that can be sent back to the client.
 /// </summary>
 /// <param name="command">Command to enqueue</param>
 /// <returns>Task</returns>
 /// <exception cref="ArgumentException">Thrown if the command type is illegal</exception>
 private async Task EnqueueCommand(BaseCommand command)
 {
     if (SupportedCommands.Contains(command.GetType()) || Command.SupportedCommands.Contains(command.GetType()))
     {
         await _commandQueue.AddAsync(command);
     }
     else
     {
         throw new ArgumentException($"Invalid command {command.Command} (wrong mode?)");
     }
 }
コード例 #10
0
        async void Example13()
        {
            AsyncCollection <int> _asyncStack = new AsyncCollection <int>(new ConcurrentStack <int>()); //后进先出(栈)
            AsyncCollection <int> _asyncBag   = new AsyncCollection <int>(new ConcurrentBag <int>());   //无序(包)

            //在栈的项目次序上有竞态条件。单线程中如果先运行生存者代码,后运行消费者代码,那项目的次序就像一个普通的栈
            //生存者代码
            await _asyncStack.AddAsync(7);

            await _asyncStack.AddAsync(13);

            _asyncStack.CompleteAdding();
            //消费者代码
            //先显示“13”,后显示“7”
            while (await _asyncStack.OutputAvailableAsync())
            {
                Trace.WriteLine(_asyncStack.TakeAsync());
            }

            //当生产者和消费者都并发运行时(这是常见情况),消费者总是会得到最近加入的项目。这导致这个集合从整体上看不像是一个栈。当然了,包是根本没有次序的。
        }
コード例 #11
0
    async Task Test()
    {
        var _asyncStack = new AsyncCollection <int>(
            new ConcurrentStack <int>());
        var _asyncBag = new AsyncCollection <int>(
            new ConcurrentBag <int>());


        // Producer code
        await _asyncStack.AddAsync(7);

        await _asyncStack.AddAsync(13);

        _asyncStack.CompleteAdding();

        // Consumer code
        // Displays "13" followed by "7".
        while (await _asyncStack.OutputAvailableAsync())
        {
            Trace.WriteLine(await _asyncStack.TakeAsync());
        }
    }
コード例 #12
0
        public async Task Process(CancellationToken cancellationToken)
        {
            while (await input.OutputAvailableAsync(cancellationToken).ConfigureAwait(false))
            {
                var item = await input.TakeAsync(cancellationToken).ConfigureAwait(false);

                logger.ConditionalDebug("Processing \"{0}\"", item.Title);

                // Do not pass a CancellationToken, so that the operation cannot be interrupted.
                var torrentItem = new Torrent(item.Url, true, item.Title);
                await output.AddAsync(torrentItem).ConfigureAwait(false);
            }
        }
コード例 #13
0
        private async Task EnqueueMatchAsync(FeedItem item, CancellationToken cancellationToken)
        {
            logger.ConditionalDebug("Enqueueing matched item: \"{0}\"", item.Title);

            if (Uri.TryCreate(item.Link, UriKind.Absolute, out Uri matchUrl))
            {
                var match = new FeedItemMatch(item.Title, matchUrl);
                await output.AddAsync(match, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                logger.Error("Failed to create Uri from \"{0}\". Ignoring item.", item.Link);
            }
        }
コード例 #14
0
        /// <summary>
        /// Called by the <see cref="Code"/> implementation to check if the client wants to intercept a G/M/T-code
        /// </summary>
        /// <param name="code">Code to intercept</param>
        /// <returns>True if the code has been resolved</returns>
        /// <exception cref="OperationCanceledException">Code has been cancelled</exception>
        private async Task <bool> Intercept(Code code)
        {
            // Avoid race conditions. A client can deal with only one code at once!
            using (await _lock.LockAsync(Program.CancelSource.Token))
            {
                // Send it to the IPC client
                await _codeQueue.AddAsync(code);

                // Keep on processing commands from the interceptor until a handling result is returned.
                // This must be either a Cancel, Ignore, or Resolve instruction!
                try
                {
                    if (await _commandQueue.OutputAvailableAsync(Program.CancelSource.Token))
                    {
                        BaseCommand command = await _commandQueue.TakeAsync(Program.CancelSource.Token);

                        // Code is cancelled. This invokes an OperationCanceledException on the code's task.
                        if (command is Cancel)
                        {
                            throw new OperationCanceledException();
                        }

                        // Code is resolved with a given result and the request is acknowledged
                        if (command is Resolve resolveCommand)
                        {
                            code.Result = (resolveCommand.Content == null) ? new CodeResult() : new CodeResult(resolveCommand.Type, resolveCommand.Content);
                            return(true);
                        }

                        // Code is ignored. Don't do anything
                    }
                }
                catch (Exception e) when(!(e is OperationCanceledException))
                {
                    _codeQueue.CompleteAdding();
                    Console.WriteLine($"[err] Interception handler enocuntered an exception: {e}");
                }
            }
            return(false);
        }
コード例 #15
0
        /// <summary>
        /// Called by the <see cref="Code"/> implementation to check if the client wants to intercept a G/M/T-code
        /// </summary>
        /// <param name="code">Code to intercept</param>
        /// <returns>True if the code has been resolved</returns>
        /// <exception cref="OperationCanceledException">Code has been cancelled</exception>
        private async Task <bool> Intercept(Code code)
        {
            // Send it to the IPC client
            await _codeQueue.AddAsync(code);

            // Keep on processing commands from the interceptor until a handling result is returned.
            // This must be either a Cancel, Ignore, or Resolve instruction!
            try
            {
                if (await _commandQueue.OutputAvailableAsync(Program.CancellationToken))
                {
                    BaseCommand command = await _commandQueue.TakeAsync(Program.CancellationToken);

                    // Code is cancelled. This invokes an OperationCanceledException on the code's task.
                    if (command is Cancel)
                    {
                        throw new OperationCanceledException();
                    }

                    // Code is resolved with a given result and the request is acknowledged
                    if (command is Resolve resolveCommand)
                    {
                        code.Result = (resolveCommand.Content == null) ? new CodeResult() : new CodeResult(resolveCommand.Type, resolveCommand.Content);
                        return(true);
                    }

                    // Code is ignored. Don't do anything
                }
            }
            catch (Exception e) when(!(e is OperationCanceledException))
            {
                _codeQueue.CompleteAdding();
                Connection.Logger.Error(e, "Interception processor caught an exception");
            }
            return(false);
        }
コード例 #16
0
        public DfTask Run(Func <Task> action)
        {
            var task = new DfTask();

            var currentListOfVisitedNodes = ListOfVisitedNodes.Current.Value ?? (ListOfVisitedNodes.Current.Value = new ListOfVisitedNodes());

            var firstVisit = !currentListOfVisitedNodes.VisitedNodes.Contains(nodeId);

            if (firstVisit)
            {
                currentListOfVisitedNodes.VisitedNodes.Add(nodeId);
            }

            Func <Task> runAction = async() =>
            {
                Exception exception = null;

                try
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        exception = new OperationCanceledException(cancellationToken);
                    }
                    else
                    {
                        await action();
                    }
                }
                catch (Exception ex)
                {
                    exception = ex;
                }

                ListOfVisitedNodes.Current.Value = currentListOfVisitedNodes;

                DfTask.AsyncBlockingTask = null;

                if (exception == null)
                {
                    task.SetResult();
                }
                else
                {
                    task.SetException(exception);
                }

                if (DfTask.AsyncBlockingTask != null)
                {
                    await DfTask.AsyncBlockingTask;
                }
            };

            Func <Task> actionToAddToCollection =
                Utilities.MakeActionRunInCurrentExecutionContextIfAny(runAction);

            ListOfVisitedNodes.Current.Value = null;

            if (firstVisit)
            {
                DfTask.AsyncBlockingTask = collection.AddAsync(actionToAddToCollection);
            }
            else
            {
                DfTask.AsyncBlockingTask = collectionForReentrantItems.AddAsync(actionToAddToCollection);
            }

            return(task);
        }
コード例 #17
0
 public async Task ReceiveAsync(byte[] data, CancellationToken cancellation)
 {
     using (var linked = CancellationTokenSource.CreateLinkedTokenSource(cancellation, CancelBrook.Token))
         await ReadQueue.AddAsync(data, linked.Token);
 }
コード例 #18
0
 /// <summary>
 /// Merge received data into the object model
 /// </summary>
 /// <param name="module">Module that is supposed to be merged</param>
 /// <param name="json">JSON data</param>
 /// <returns>Asynchronous task</returns>
 public static Task MergeData(byte module, byte[] json) => _statusUpdates.AddAsync(new Tuple <byte, byte[]>(module, json));
コード例 #19
0
        async Task Main(string[] args)
        {
            //不可变集合是永远不会改变的集合,写入操作会返回新实例,不可变集合之间通常共享了大部分存储空间,浪费不大。多个线程访问安全

            ///不可变栈
            var list = ImmutableStack <int> .Empty;

            list = list.Push(13);
            list = list.Push(15);

            foreach (var item in list)
            {
                Console.WriteLine(item);
            }
            ///不可变队列 ImmutableQueue

            //不可变列表
            //支持索引、不经常修改、可以被多个线程安全访问
            var immutlist = ImmutableList <int> .Empty;

            immutlist = immutlist.Insert(0, 13);
            immutlist = immutlist.Insert(0, 7);

            //不可变set集合
            //不需要存放重复内容,不经常修改,可以被多个线程安全访问
            //ImmutableHashSet 不含重复元素的集合
            //ImmutableSortedSet 已排序不含重复元素的集合


            //不可变字典
            //ImmutableSortedDictionary
            //ImmutableDictionary



            //线程安全集合是可同时被多个线程修改的可变集合,线程安全集合混合使用了细粒度锁定和无锁技术,优点是多个线程可安全地对其进行访问
            //线程安全字典
            //需要有一个键/值集合,多个线程同时读写时仍能保持同步
            //ConcurrentDictionary
            var dictionary = new ConcurrentDictionary <int, string>();

            //第一个委托把本来的键0转换成值zero,第二个委托把键0和原来的值转换成字典中修改后的值 zero,只有字典中已民存在这个键时,最后一个委托才会运行
            dictionary[0] = "zero";
            var newValue = dictionary.AddOrUpdate(0, key => "Zero", (key, oldValue) => "Zero1");

            dictionary.TryGetValue(0, out string currentalue);
            Console.WriteLine(currentalue);
            dictionary.TryRemove(0, out string removeValue);


            //生产费消费者模型
            //阻塞队列
            //需要有一个管道,在进行之间传递消息或数据,例如一个线程下大装载数据,装载的同时把数据压进管道,与此同时,另一个线程在管道的接收端接收处理数据
            //BlockingCollection 类可当做这种管道,阻塞队列,先进先出 限流 bounedCapacity属性
            //不过如果用到这个的话,更推荐数据流
            var blockqueue     = new BlockingCollection <int>();
            var blockqueueTask = Task.Factory.StartNew(() =>
            {
                blockqueue.Add(7);
                blockqueue.Add(8);
                blockqueue.Add(9);
                blockqueue.CompleteAdding();
            });

            foreach (var item in blockqueue.GetConsumingEnumerable())
            {
                Console.WriteLine(item);
            }
            await blockqueueTask;

            //阻塞栈和包
            //首先有一个管道,在线程之间传递消息或数据,但不想(不需要)这个管道使用先进先出的语义
            //blockingCollection 可以在创建时选择规则
            var _blockingStack = new BlockingCollection <int>(new ConcurrentBag <int>());


            //异步队列
            //在代码的各个部分之间以选进先出的方式传递消息或数据 多个消费者时需要注意捕获InvalidOperationException异常
            var _syncQueue = new BufferBlock <int>();
            await _syncQueue.SendAsync(7);

            await _syncQueue.SendAsync(13);

            _syncQueue.Complete();


            while (await _syncQueue.OutputAvailableAsync())
            {
                Console.WriteLine(await _syncQueue.ReceiveAsync());
            }


            //异步栈和包
            //需要有一个管道,在程序的各个部分传递数据,但不希望先进先出
            var _asyncStack = new AsyncCollection <int>(new ConcurrentBag <int>(), maxCount: 1);
            //这个添加操作会立即完成,下一个添加会等待7被移除后
            await _asyncStack.AddAsync(7);

            _asyncStack.CompleteAdding();
            while (await _asyncStack.OutputAvailableAsync())
            {
                var taskReuslt = await _asyncStack.TryTakeAsync();

                if (taskReuslt.Success)
                {
                    Console.WriteLine(taskReuslt.Item);
                }
            }


            //阻塞/异步队列
            //先进先出 足够灵活 同步或异步方式处理
            var queue = new  BufferBlock <int>();
            await queue.SendAsync(1);

            queue.Complete();

            while (await queue.OutputAvailableAsync())
            {
                Console.WriteLine(await queue.ReceiveAsync());
            }



            Console.WriteLine("Hello World!");
        }
コード例 #20
0
 public async void SendAsync(byte[] message)
 {
     var packet = Data.AddSizeToMessage(message);
     await SendQueue.AddAsync(packet);
 }
コード例 #21
0
ファイル: BytesBuffer.cs プロジェクト: Nero0909/FileManager
 public async Task FreeSegmentAsync(ArraySegment <byte> segment, CancellationToken token)
 {
     await _emptySegments.AddAsync(segment.Offset, token);
 }
コード例 #22
0
        async void ReceiveAsync()
        {
            try
            {
                while (true)
                {
                    var packet = await ProtobufEx.DeserializeWithLengthPrefixAsync <MultiplexPacket>(Inner, PrefixStyle.Base128, CancelAll.Token);

                    if (packet.SubstreamId != 0)
                    {
                        InboundSubstream = -packet.SubstreamId;
                    }
                    else if (InboundSubstream == 0)
                    {
                        throw new FormatException();
                    }
                    MultiplexSubstream substream;
                    bool created = false;
                    lock (Substreams)
                    {
                        if (!Substreams.TryGetValue(InboundSubstream, out substream) && InboundSubstream < 0)
                        {
                            Substreams[InboundSubstream] = substream = new MultiplexSubstream(this, InboundSubstream);
                            created = true;
                        }
                    }
                    if (created)
                    {
                        await Pending.AddAsync(substream, CancelAll.Token);
                    }
                    if (substream != null)
                    {
                        if (packet.Data != null && packet.Data.Length > 0)
                        {
                            await substream.ReceiveAsync(packet.Data, CancelAll.Token);
                        }
                        if (packet.EndOfStream)
                        {
                            await substream.ReceiveEndOfStream(CancelAll.Token);
                        }
                    }
                }
            }
            catch (EndOfStreamException)
            {
                Dispose();
                List <MultiplexSubstream> substreams;
                lock (Substreams)
                    substreams = Substreams.Values.ToList();
                foreach (var substream in substreams)
                {
                    substream.Dispose();
                }
            }
            catch (Exception e)
            {
                if (!CancelAll.Token.IsCancellationRequested)
                {
                    Logger.Error(e);
                    Dispose();
                }
            }
        }
コード例 #23
0
        /// <summary>
        /// Waits for commands to be received and enqueues them in a concurrent queue so that a <see cref="Code"/>
        /// can decide when to cancel/resume/resolve the execution.
        /// </summary>
        /// <returns>Task that represents the lifecycle of the connection</returns>
        public override async Task Process()
        {
            try
            {
                do
                {
                    // Read another code from the interceptor
                    if (await _codeQueue.OutputAvailableAsync(Program.CancelSource.Token))
                    {
                        Code code = await _codeQueue.TakeAsync(Program.CancelSource.Token);

                        await Connection.Send(code);
                    }
                    else
                    {
                        break;
                    }

                    // Keep processing commands until an action for the code has been received
                    BaseCommand command;
                    do
                    {
                        // Read another command from the IPC connection
                        command = await Connection.ReceiveCommand();

                        if (command == null)
                        {
                            break;
                        }

                        if (Command.SupportedCommands.Contains(command.GetType()))
                        {
                            // Interpret regular Command codes here
                            object result = command.Invoke();
                            await Connection.SendResponse(result);
                        }
                        else if (SupportedCommands.Contains(command.GetType()))
                        {
                            // Send other commands to the task intercepting the code
                            await _commandQueue.AddAsync(command);

                            break;
                        }
                        else
                        {
                            // Take care of unsupported commands
                            throw new ArgumentException($"Invalid command {command.Command} (wrong mode?)");
                        }
                    }while (!Program.CancelSource.IsCancellationRequested);

                    // Stop if the connection has been terminated
                    if (command == null)
                    {
                        break;
                    }
                }while (!Program.CancelSource.IsCancellationRequested);
            }
            catch (SocketException)
            {
                // IPC client has closed the connection
            }
            finally
            {
                _commandQueue.CompleteAdding();
                _interceptors.TryRemove(this, out _);
            }
        }