TPL数据流块,它将消息的前向延迟到下一个块

时间:2014-07-09 13:12:35

标签: c# .net task-parallel-library tpl-dataflow

我需要一个Dataflow块,它根据消息中的时间戳(LogEntry)将消息的转发延迟到下一个块。

这是我想出来的但感觉不对。有任何改进建议吗?

  private IPropagatorBlock<LogEntry, LogEntry> DelayedForwardBlock()
    {
        var buffer = new ConcurrentQueue<LogEntry>();

        var source = new BufferBlock<LogEntry>();

        var target = new ActionBlock<LogEntry>(item =>
        {
            buffer.Enqueue(item);
        });


        Task.Run(() =>
            {
                LogEntry entry;
                while (true)
                {
                    entry = null;
                    if (buffer.TryPeek(out entry))
                    {
                        if (entry.UtcTimestamp < (DateTime.UtcNow - TimeSpan.FromMinutes(5)))
                        {
                            buffer.TryDequeue(out entry);
                            source.Post(entry);
                        }
                    }
                }
            });


        target.Completion.ContinueWith(delegate
        {
            LogEntry entry;
            while (buffer.TryDequeue(out entry))
            {
                source.Post(entry);
            }

            source.Complete();
        });

        return DataflowBlock.Encapsulate(target, source);
    }

1 个答案:

答案 0 :(得分:10)

你可以简单地使用一个TransformBlock,使用Task.Delay异步等待延迟:

IPropagatorBlock<TItem, TItem> DelayedForwardBlock<TItem>(TimeSpan delay)
{
    return new TransformBlock<TItem, TItem>(async item =>
    {
        await Task.Delay(delay);
        return item;
    });
}

用法:

var block = DelayedForwardBlock<LogEntry>(TimeSpan.FromMinutes(5));