Thursday, November 04, 2010 8:04 PM
The dataflow blocks API does a good job of supporting both "push" and "pull" semantics.
One piece that seems to be missing is a BufferBlock of bounded size to act as a throttling mechanism. Are there any plans to add this (or alternative approaches)?
Programming blog: http://nitoprograms.blogspot.com/
Including my TCP/IP .NET Sockets FAQ
and How to Implement IDisposable and Finalizers: 3 Easy Rules
Microsoft Certified Professional Developer
How to get to Heaven according to the Bible
- Moved by Stephen Toub - MSFTMicrosoft Employee, Owner Friday, February 04, 2011 5:33 PM New TPL Dataflow forum (From:Visual Studio Async CTP)
Thursday, November 04, 2010 9:38 PMOwner
We're definitely considering it, so it's good to know you're interested. Can you elaborate on how you'd like to use it and on the various behaviors you'd expect from it? For example, if code explicitly Post's to such a bounded buffer, would you want that Post to block until room was available, or would you want it to return false indicating that the data couldn't be accepted? Similarly, I assume that you'd want a bounded buffer to postpone messages that it didn't yet have room to accept?
Friday, February 04, 2011 5:14 PMAn unbounded buffer is seldomly a good idea imo. It leads to heisenbugs (sporadic OOM). There is really no difference between an ordinary race condition and an unbounded buffer.
Friday, February 04, 2011 5:32 PMOwnerThe latest preview of TPL Dataflow, available at http://msdn.microsoft.com/en-us/devlabs/gg585582, has bounding support built into BufferBlock. You can configure it to be either unbounded or bounded with a capacity supplied at construction.
- Marked As Answer by Stephen Toub - MSFTMicrosoft Employee, Owner Friday, February 04, 2011 5:33 PM
Friday, March 04, 2011 9:42 AM
Hello Stephen et al.,
I've set up dataflow using a bounded BufferBlock in the middle, assuming this would allow me to throttle data flow. I should say I downloaded the library only yesterday so I'd assume I have the version with the bounded BufferBlock support.
Here's a code snippet that shows how the blocks are created and connected:
myDirectoryProcessor = new TransformManyBlock<Directory, File>((Func<Directory, IEnumerable<File>>) ProcessDirectory, new DataflowBlockOptions(TaskScheduler.Default)); myFileProcessor = new ActionBlock<File>((Action<File>) ProcessFile, new DataflowBlockOptions(TaskScheduler.Default, 16)); var bufferBlock = new BufferBlock<File>(10); myDirectoryProcessor.LinkTo(bufferBlock); bufferBlock.LinkTo(myFileProcessor);
It just doesn't seem to work, frankly the BufferBlock doesn't actually do any throttling. The 'InputCount' property on "myFileProcessor" keeps growing (the 'ProcessDirectory' method produces results faster than the 'ProcessFile' method can handle, even if the latter is executed with a parallelism of 16 in this case).
It's well possible that I've missed something if so please let me know.
[Update] Sorry, my bad, indeed I was missing something. The fact that the file processor block is greedy means it takes items from the buffer as soon as any are added, this really does make the buffer pointless. I've changed the file processor to be non-greedy, and lo-and-behold! it works as expected, and the throttling effect works.[/Update]