我正在学习TPL数据流,我已经看到它通过我的一些朋友的力量,我遇到了我的实施问题。
我想要/需要的是尽可能快地发送消息。我在LinqPad中做了一些原型设计,这是我到目前为止所做的:
// Holds all the messages for my loadMessage ActionBlock to grab its data from
var bufferBlock = new BufferBlock<string>();
// Sends message to where it needs to go as fast as it can.
var loadMessage = new ActionBlock<string>(msg =>
{
msg.Dump();
},
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded
});
// Links the blocks together
bufferBlock.LinkTo(loadMessage);
// Loads the Buffer
for (int i = 0; i < 10; i++)
{
bufferBlock.Post("This is a message");
}
//Calls completion to stop threads
bufferBlock.Complete();
loadMessage.Complete();
问题是loadMessageBlock没有转储上面示例中的消息。我一直在寻找一些运气不佳的见解。我想我错过了TPL的基本功能。我的理解是BufferBlock保存要由其他块处理的信息,而ActionBlocked(链接到BufferBlock)应该从缓冲区中获取数据并执行它需要做的事情。将信息放在缓冲区停止完成的For循环之后,调用停止线程。
在我的实现中,我有一个Parallel.For,它运行我的loadMessage中的代码就好了。我只是无法实现TPL来做我想做的事情,我的理解是TPL将比Parallel.For快。
我是否认为这可以起作用?我错误地使用了TPL吗?我将继续研究答案,任何指针都将受到高度赞赏。谢谢!
答案 0 :(得分:1)
首先,关于术语的说明:TPL(任务并行库的缩写)与TPL数据流不同,它只是一个子集。 TPL整体包含Parallel.For()
和Task
类型等内容。
现在,您的代码存在的问题是您过早地完成了loadMessage
阻止。致电Complete()
后,该区块不再接受任何邮件,因此您发布到bufferBlock
的邮件将永远不会到达loadMessage
。
您需要的是仅在loadMessage
向其发送所有消息后才完成bufferBlock
。这正是PropagateCompletion
所做的:
bufferBlock.LinkTo(
loadMessage, new DataflowLinkOptions { PropagateCompletion = true });
// post your data to bufferBlock here
bufferBlock.Complete();
await loadMessage.Completion;
此外,在这种特定情况下,根本不需要bufferBlock
,您可以直接将消息发布到loadMessage
。
我的理解是TPL比Parallel.For
更快
我不明白为什么一般来说应该更快。在正常情况下,他们的表现应该具有可比性。所以你应该更好地使用适合你问题的那个,而不是选择一个因为“它更快”。如果你真的非常关心性能,那就用两种方式编写代码并测量哪一个更好。
答案 1 :(得分:-2)
我想要/需要的是尽可能快地发送消息:
要实现这一点,您需要在缓冲区块中同时发送/接收数据。以下是摘录:
var bufferBlock = new BufferBlock<string>();
// Write to and read from the message block concurrently.
var post01 = Task.Run(() =>
{
// Loads the Buffer
for (int i = 0; i < 10; i++)
{
bufferBlock.Post(string.Format("This is a message {0}",i));
}
});
var receive = Task.Run(() =>
{
for (int i = 0; i < 10; i++)
{
var message = bufferBlock.Receive();
message.Dump();
}
});
Task.WaitAll(post01, receive);
有关详细信息,请参阅MSDN link
我的理解是TPL比Parallel.For。
更快
这不正确,因为它们使用相同的底层结构。它们属于同一名称空间System.Threading.Tasks