【问题标题】:Async stack equivalent of TPL Dataflow BufferBlock<T>等效于 TPL 数据流 BufferBlock<T> 的异步堆栈
【发布时间】:2014-05-26 03:51:19
【问题描述】:

BufferBlock&lt;T&gt; 是一个非常好的队列异步接口。

我正在寻找类似的东西,但对于 LIFO 堆栈。当通过ConcurrentStack 时,我正在寻找与BlockingCollection 等效的功能,但我不想在Take 和Add 上阻塞线程,我想要TakeAsyncAddAsync。这基本上是 BufferBlock&lt;T&gt; 给我的,但它是一个 FIFO 队列,我需要一个 LIFO 堆栈。

我正在寻找异步堆栈的无锁版本。我不在乎它是否适合数据流,我只是以BufferBlock 为例。我不打算将它与数据流结合使用。

【问题讨论】:

    标签: c# .net concurrency async-await tpl-dataflow


    【解决方案1】:

    TPL Dataflow当然不支持这样的功能,否则就不会有“流”。

    您可以使用 Stephen Cleary 的 AsyncCollection。它是任何 IProducerConsumerCollection 的异步包装器,在您的情况下可能是 ConcurrentStack

    var stack = new ConcurrentStack<int>();
    var asyncStack = new AsyncCollection<int>(stack);
    
    await asyncStack.AddAsync(4);
    await asyncStack.AddAsync(6);
    
    int top = await asyncStack.TakeAsync();
    

    【讨论】:

    • 是的,我知道 TPL 数据流没有这个功能,这就是我问这个问题的原因。 Stephen Cleary 的 AsyncCollection 有许多锁和其他效率较低的技术。我正在寻找无锁版本。我将更新问题以包含该详细信息。
    • @AaronStainback 我没有在 AsyncCollection 中看到任何锁,除非你计算 AsyncLock 并且你真的不应该。我非常怀疑您能否找到更有效的解决方案。但是,如果您认为可以改进它,我们随时欢迎您。
    • 我的异步原语内部有锁。但这些几乎总是没有争议的。当您进入异步协调时,异步/任务语义将同步“提升”到用户空间代码中。所以,锁只用于保护内部状态,而不是用于协调(非常类似于how locks are used internally by BufferBlock&lt;T&gt;)。由于这种“提升”和lock 的自旋+块语义,IMO 不需要无锁异步协调原语。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多