从您引用的 MSDN 页面:
因为运行时管理数据之间的依赖关系,您通常可以避免同步访问共享数据的要求。
这意味着当您在代码中使用数据流块时,您通常不必担心同步,因为这些块会为您完成这些。
但是当您编写自定义数据流块时,您确实需要自己处理同步。例如,假设您正在实施BufferBlock
. 调用Post()
该块必须以某种方式同步,因为两个源块可以Post()
同时调用。没有人会为你处理同步,所以你的Post()
* 实现需要使用锁或ConcurrentQueue
类似的东西。
* 实际上,你不执行Post()
,你执行OfferMessage()
。
但是,如果我正确理解您的要求,您实际上可以通过利用 TDF 中已经存在的同步来实现您的块而无需任何手动同步。您将通过使用两个BufferBlock
s、一个助手Task
和来实现您的块DataflowBlock.Encapsulate()
:
public static IPropagatorBlock<T, T> CreateDelayedBlock<T>(TimeSpan delay)
{
var source = new BufferBlock<T>();
var target = new BufferBlock<T>();
Task.Run(
async () =>
{
while (await source.OutputAvailableAsync())
{
T item;
if (source.TryReceive(out item))
{
await Task.Delay(delay);
await target.SendAsync(item);
}
else
{
// this shouldn't happen
// nobody else should be able to receive from source
}
}
// TODO: if source failed, fail target
target.Complete();
});
return DataflowBlock.Encapsulate(source, target);
}