BufferBlock deadlock with OutputAvailableAsync after TryReceiveAll

前端 未结 2 1801
闹比i
闹比i 2021-01-31 18:29

While working on an answer to this question, I wrote this snippet:

var buffer = new BufferBlock();
var producer = Task.Run(async () =>
{
    whi         


        
      
      
      
2条回答
  •  南方客
    南方客 (楼主)
    2021-01-31 19:18

    Alas, it's the end of September 2015, and although i3arnon fixed the error it is not solved in the version that was released two days after the error was fixed: Microsoft TPL Dataflow version 4.5.24.

    However IReceivableSourceBlock.TryReceive(...) works correctly. An extension method will solve the problem. After a new release of TPL Dataflow it will be easy to change the extension method.

    /// 
    /// This extension method returns all available items in the IReceivableSourceBlock
    /// or an empty sequence if nothing is available. The functin does not wait.
    /// 
    /// The type of items stored in the IReceivableSourceBlock
    /// the source where the items should be extracted from 
    /// The IList with the received items. Empty if no items were available
    public static IList TryReceiveAllEx(this IReceivableSourceBlock buffer)
    {
        /* Microsoft TPL Dataflow version 4.5.24 contains a bug in TryReceiveAll
         * Hence this function uses TryReceive until nothing is available anymore
         * */
        IList receivedItems = new List();
        T receivedItem = default(T);
        while (buffer.TryReceive(out receivedItem))
        {
            receivedItems.Add(receivedItem);
        }
        return receivedItems;
    }
    

    usage:

    while (await this.bufferBlock.OutputAvailableAsync())
    {
        // some data available
        var receivedItems = this.bufferBlock.TryReceiveAllEx();
        if (receivedItems.Any())
        {
            ProcessReceivedItems(bufferBlock);
        }
    }
    

提交回复
热议问题