Reputation: 23833
All, I have used the Thread
and BackgroundWorker
classes with success to facilitate a smooth UI for a few small-scale applications. I have recently been given the job of converting a huge piece of code from serial to multi-threaded and I have some questions due to some comments I have seen on this very site. The code I have to convert makes a varying amount (usually a large number) of calls to SQL Server and these SQL queries can sometimes run for 30 minutes or so. As such, multi-threading is required.
I have already setup a test program using BackgroundWorker
and these run well. However, some say that due to the BackgroundWorker
using the Thread-Pool they should not be used for long running tasks. I have not read this anywhere (i.e. Joesph Albahari C# 4.0 In a Nutshell), and this contradicts MSDN. Should I be using BackgroundWorker
or Thread
for such purposes?
Thanks in advance.
Upvotes: 5
Views: 1529
Reputation: 75296
BackgroundWorker
is appropriate to use for long-running tasks. It's threads from the ThreadPool
that you shouldn't use for long-running tasks (BackgroundWorker
does not use thread pool threads).
Also, a 30-minute SQL query is definitely a code smell. You might want to investigate what's going on there and see if you can speed things up.
Edit: I'm wrong - BackgroundWorker
does use thread pool threads. I'm leaving this answer up for the discussion below.
Upvotes: 2
Reputation: 5355
The ThreadPool
has a maximum number of active threads (GetMaxThreads
/SetMaxThreads
). Any tasks above that number will remain queued until a ThreadPool
thread is available. For the purposes of this example, let's say that the max thread count is 10. If you spawn 10 queries through BackgroundWorker
and each of them completes in 30 minutes, any other tasks queued on the ThreadPool
will not run until after 30 minutes.
That task could just be a trivial tick from a Timer
that updates a clock you have on the UI. This could be problematic since that clock could then be stuck for half an hour until a thread is available. Realistically though, MaxThreads
is certainly greater than 10. Mine is 1023 (.NET 4, 2x2.26GHz laptop). So, hopefully you won't run into this issue if you decide to stick with BackgroundWorker
. Still it's useful to understand why it's generally not advised to have long-running tasks on the ThreadPool
.
Personally, I'd use dedicated threads just to be safe. Especially since the threads will certainly be idle while waiting for your queries to complete. The only advantage I see to using BackgroundWorker
in your case is that it's easier to update a progress bar on the UI. But if you're not displaying the progress of your query, that's another reason to use dedicated threads.
Upvotes: 1
Reputation: 116401
The idea behind the threadpool is that it reuses threads and thus amortizes the cost of creating new threads. Creating a thread may be a very expensive operation, so it makes sense reuse threads if possible. If you schedule long running jobs on the threadpool, you force it to create additional threads and thus reduce the benefit of reusing threads.
Upvotes: 3