Jerry Nixon on Windows: How to Throttle Async Operations (against a List)

Jerry Nixon on Windows

Wednesday, January 26, 2011

How to Throttle Async Operations (against a List)

So I had this requirement to execute an operation against a list of records. Specifically, to call a service for each one independently. We also wanted the UI to reflect what was running, and it's start stop events.

Sample situation: you have 55 records in a grid of 200 that you need to save changes to. You know the service will timeout if you send them all. You need to send one at a time, maybe 5 at a time, but that's variable. You also want to reflect in the grid the status of the save operation. This is for you.

This is not a simple threading exercize because I wanted to throttle the simultaneous threads through queuing without using the ThreadPool that shares with the Application Domain. I needed my own queue.

It's also a challenge because a new thread is not on the UI thread, and returning the thread to the UI thread from the new, async thread is not easy. So I leveraged the native framework objects, and extended them.

I call it the MultiBackgroundWorker, in part because it leverages the ComponentModel class. I started this excerise with the ThreadPool and eventually landed here - I avoided Semaphores for the same reasons.

I tested this with a 30,000 items and 50,000 simultaneous threads. It works. The real consideration is the operation itself; how much can your system (in my case our service) handle at once? We chose 5.

It's pretty nice. Have fun.

Here's the code: