none
AsUnordered()

    คำถาม

  • Is there any way to tell a block with MaxDegreeOfParallelism > 1 that you don't care about ordering and want to utilize this to lessen latency?

    I take it the workaround is to create and subscribe multiple identical blocks, each with a MaxDegreeOfParallelism of 1, and combine their outputs into a single BufferBlock. (If there was a .Clone() method, this might be easier).


    Write LINQ queries interactively - www.linqpad.net
    15 สิงหาคม 2554 3:15

คำตอบ

  • Right.  Or you could have the ActionBlock use SendAsync instead of Post, such that you could then wait on the returned task before processing another item.  That would then allow the ActionBlock to take part in back pressure. You could either .Wait() on the SendAsync task, or await it, or just return it from the ActionBlock's delegate (using the Func<Task> overload) so that the ActionBlock itself directly monitors the SendAsync.
    • ทำเครื่องหมายเป็นคำตอบโดย Joe AlbahariMVP 16 สิงหาคม 2554 4:25
    15 สิงหาคม 2554 14:06
    เจ้าของ
  • Hi Joe-

    Right now, no, there isn't such an option.  The only blocks such an option would affect right now would be TransformBlock and TransformManyBlock, and while we've considered exposing such an option, it hasn't popped up to the top of the list of things to expose.  Have you found this problematic?  It would potentially impact the scenario where, with DOP>1 in a TransformBlock or TransformManyBlock, message N takes significantly longer to process than message N+1, and thus N+1 can't be propagated to a subsequent target until N completes.  If it is problematic, you can work around it with an ActionBlock that Posts to a subsequent target rather a TransformBlock linked to one... ActionBlock doesn't go through an output reordering buffer, since it doesn't have an output queue at all.

    15 สิงหาคม 2554 6:02
    เจ้าของ

ตอบทั้งหมด

  • Hi Joe-

    Right now, no, there isn't such an option.  The only blocks such an option would affect right now would be TransformBlock and TransformManyBlock, and while we've considered exposing such an option, it hasn't popped up to the top of the list of things to expose.  Have you found this problematic?  It would potentially impact the scenario where, with DOP>1 in a TransformBlock or TransformManyBlock, message N takes significantly longer to process than message N+1, and thus N+1 can't be propagated to a subsequent target until N completes.  If it is problematic, you can work around it with an ActionBlock that Posts to a subsequent target rather a TransformBlock linked to one... ActionBlock doesn't go through an output reordering buffer, since it doesn't have an output queue at all.

    15 สิงหาคม 2554 6:02
    เจ้าของ
  • I don't have a specific scenario - I was just curious.

    Regarding the workaround, presumably this would be applicable if either the target blocks were unbounded, or you didn't want to defer the ActionBlock itself if the target blocks were full.


    Write LINQ queries interactively - www.linqpad.net
    15 สิงหาคม 2554 13:29
  • Right.  Or you could have the ActionBlock use SendAsync instead of Post, such that you could then wait on the returned task before processing another item.  That would then allow the ActionBlock to take part in back pressure. You could either .Wait() on the SendAsync task, or await it, or just return it from the ActionBlock's delegate (using the Func<Task> overload) so that the ActionBlock itself directly monitors the SendAsync.
    • ทำเครื่องหมายเป็นคำตอบโดย Joe AlbahariMVP 16 สิงหาคม 2554 4:25
    15 สิงหาคม 2554 14:06
    เจ้าของ
  • Got you. I notice a similar workaround for implementing a BroadcastBlock that doesn't drop messages.

    This seems like a useful composition pattern - rather than linking, calling SendAsync and awaiting the task.


    Write LINQ queries interactively - www.linqpad.net
    16 สิงหาคม 2554 4:25