带有BroadcastBlock的TPL数据流生产者/消费者 - 跟踪执行

时间:2015-10-02 15:33:25

标签: c# execution producer-consumer tpl-dataflow

这是我的情景:多个生产者,单个消费者。消费者同步工作,并且应该只处理最后一个输入(甚至是当前正在处理的内容的中止处理,如果有的话,则以新输入开始)。

所以我已将BroadcastBlock与ActionBlock连接

var broadcastBlock = new BroadcastBlock<PresenceStateChange>((input) => input,     new DataflowBlockOptions { CancellationToken = serverShutDownSource.Token });
var processTeamPresenceUpdateBlock = new     ActionBlock<PresenceStateChange>((data) => processData(data), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1 });
broadcastBlock.LinkTo(processTeamPresenceUpdateBlock, new DataflowLinkOptions { PropagateCompletion = true });

我使用的数据类包含应该处理的数据(处理涉及通过网络发送内容),以及CancellationTaskSource,以便在新数据进入管道时可以中止处理。

所以这是我的PresenceStateChange类

public class PresenceStateChange
{
    public string Data { get; set; }

    public CancellationTokenSource ShutDownSource { get; set; }
}

数据生成如下

private void generateData()
    {
        string data = null;
        lock (myLock)
        {
            data = "data element " + messageCounter;
            messageCounter++;
            if (cancelLastJobSource != null)
                cancelLastJobSource.Cancel();
            cancelLastJobSource = new CancellationTokenSource();
        }
        log("Generated data : " + data, 4);
        PresenceStateChange change = new PresenceStateChange { Data = data, ShutDownSource = cancelLastJobSource };
        broadcastBlock.Post(change);
    }

处理工作如下

private async Task processData(PresenceStateChange change)
    {
        log("processing data " + change.Data, 4);
        await Task.Delay(2000, change.ShutDownSource.Token).ConfigureAwait(false);
        if (change.ShutDownSource.IsCancellationRequested)
        {
            log("processing of data " + change.Data + ", was aborted", 3);
        }
        else
        {
            log("processing data " + change.Data + " is complete", 4);
        }
    }

这一切都很好,并做了它应该做的事情。

现在,如果我尝试将此应用于我的实际问题,则processData具有返回值。当我将数据发布到broadcastBlock时,我需要得到一些我可以等待的东西并让我知道操作是否成功(这是一个)消息是通过网络发送的 - 当前正在模拟由于发布了新消息,Task.Delay或b)处理已中止。 由于BroadcastBlock除了指示帖子是否成功之外没有返回任何内容 - 我想知道是否有办法处理我在TPL中的要求或者我是否必须寻找其他地方(并指出其他地方的指示)看起来也会受到赞赏。)

0 个答案:

没有答案