MoonKnight
MoonKnight

Reputation: 23833

Should I be using BackgroundWorker or Threads for this?

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

Answers (4)

MusiGenesis
MusiGenesis

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

Ilian
Ilian

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

Brian Rasmussen
Brian Rasmussen

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

H-Man2
H-Man2

Reputation: 3189

You can make use of asynchronous queries in ADO.NET.

Upvotes: 5

Related Questions