Generalizing asynchronous processing with BlockingCollection