I’m currently planning a Windows service. It will be a multi-threaded application which will continuously check for database records and process them. My first thoughts were to set a number of max available threads and create new thread for each process. This works OK but since I’m creating a new thread for every new process I fear that its overhead will multiply if there are lots of records to process. My question is, is this a good design or would you recommend any other solutions?
Here’s what the application will do basically:
- Check for available number of threads
- If there are available threads check the database for records to process.
- If there are records to process select top 100 of them
- Create a new process
- Call a web service for each record and update the record according to web service call result (This call+update usually take around 500ms so process will be live for about 50 seconds)
- Continue to step 1
This is currently what I am doing:
timer1.Tick += Tick();
private void Tick()
{
//do some text logging
//do some TextBox updating
}
int MaxThreads = 10
while(true)
{
if(ThreadCount < MaxThreads)
{
new Thread(() => Process()).Start();
ThreadCount++;
}
else
{
Thread.Sleep(10000);
}
}
private void Process()
{
//call ws
//update records
ThreadCount--;
}
2
You should have a look at the thread pool pattern in Wikipedia, I think this is what you are looking for. The trick is to create n threads once when your service starts, avoiding the overhead of thread creation (see this question on SO) during runtime.
As for your workflow, you may want to consider switching the first two steps:
First check if there are records to process, and if there are, see if your thread pool has a free thread. This is an optimisation problem, you want to reach the decision no processing (because there is no data, or no resources for it) with as little effort as possible. If you reach this decision more often because there is no data to process, check for this first.
Some will argue that this is premature optimisation, but I personally prefer to err a little more on the premature side.
2
.Net has a built in thread pool that you can use to do work. But even better check the Task Parallel Library in .Net 4. This makes the most common scenarios for multithreading very simple to implement. Like using Parallel.For to process in parallel. Using Task to start a work in background and waiting for all of them to finish is another approach.