I have a task that I perform in parallel; for instance printing user selected documents async’ly. One way may be to use a worker thread. But thinking of the scenario where thousands of requests pouring in onto the web server, and application is spawning one more thread for printing sounds horrible. And what if all of the concurrent users start printing?
So is the reason I want to avoid worker threads.
To work around, I have moved the code in a web service; I am calling the PrintAsync() method, and I have subscribed to OnPrintComplete to get notified. Now I can send as many prints as I want without worrying about asp.net thread starvation or blocking requests.
I know web services internally use threading, but that is IOCP threads, which means it will not bother the asp.net worker threads.
I couldn’t think of possible cons, except that it will be a web service.
Is this a good approach? What would have been a better alternate version of handling this functionality?
So you’ve described how you’re making async calls on the client and there’s actually some more questions I would ask about how you’re actually being completely async there, but it seems like your question is more about how to be as efficient as possible on the service side, right?
If you’re performing long running or I/O bound operations in your service operations, you absolutely must begin to leverage WCF’s support for asynchronous service operations. Now, there’s lots of ways to do this, but if you’re on .NET 4.0 there’s no better way than using the Task Parallel Library (TPL).
First, by offloading the work to a TPL thread you free up WCF I/O threads to handle more calls. This way your long running WCF operations don’t tie up WCF’s ability to field other operations.
Second, the TPL leverages the a thread pool by default. You don’t have to worry about every operation spinning up it’s own thread and eventually starving the machine of resources. The TPL is also smart enough to spread the work across all the cores on the box way more efficiently than you could ever do yourself without a significant investment in writing plumbing code.
Third, the TPL can be combined with the traditional Asynchronous Programming Model (APM) so that if you’re working with things like
Streams(network or file) you can use theirBeginRead/Writemethods to leverage async I/O to the max which will free up the CPU threads while blocking on reads/writes. You should absolutely be doing this to achieve maximum efficiency even if you’re not using the TPL, the TPL just makes it easier.Here’s a “bare bones” example of how you can use the TPL to implement an async service operation: