这是我的情景:多个生产者,单个消费者。消费者同步工作,并且应该只处理最后一个输入(甚至是当前正在处理的内容的中止处理,如果有的话,则以新输入开始)。
所以我已将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中的要求或者我是否必须寻找其他地方(并指出其他地方的指示)看起来也会受到赞赏。)