Recommended way to handle I/O in PPL tasks RRS feed

  • Question

  • I'm trying to figure out what the best practice is to handle potentially blocking I/O calls in code that's using PPL tasks. Based on my current understanding I see a few options but it is not clear to me what is recommended / best practice.

    One option is just to make blocking calls from a task and leave it to the runtime to manage things. I saw a comment in one thread that all std:: blocking calls are 'ConcRT aware' in VS 2012 so perhaps this is handled efficiently for that case. This still leaves the question of how to handle Win32 or non std:: I/O (WinSock, ReadFile, etc.). It seems like calls that block in the kernel will block the ConcRT worker threads and that this is one scenario that UMS was supposed to help address but UMS is no longer supported in VS 2012. This option seems nice and easy but possibly (probably?) inefficient.

    Another possibility would be to use I/O completion ports and have a separately created thread (or threads) calling GetQueuedCompletionStatus to pick up completion events. It's not clear how to best integrate this with code using PPL tasks however. It seems like it should be possible to create a fairly clean async API to wrap this with tasks using task_completion_events which could be set() on the GetQueuedCompletionStatus thread to unblock work on the worker threads but I'm not sure if this would be efficient. 

    The third option that I can see is to use blocking calls from tasks but wrap them with Context::OverSubscribe() calls allowing the runtime to spin up new worker threads so that other tasks can execute while waiting on the blocking calls. This seems like it would be a bit simpler to wrap in an API / library than the I/O completion ports approach but I'm not sure how efficient it would be or if there are potential pitfalls.

    I'm curious what approach Microsoft is taking in Casablanca or in the WinRT async APIs but I tried to step into some simple Casablanca examples and had difficulty determining how they approach this problem. It looked like they were using overlapped I/O with callbacks somehow but the overall architecture was unclear to me from the limited investigation I did.

    How are other people handling I/O when using PPL tasks? Are there any references for patterns or best practices for this?

    Wednesday, October 24, 2012 8:17 PM