views:

118

answers:

4

Senerio

We have a C# .Net Web Application that records incidents. An external database needs to be queried when an incident is approved by a supervisor. The queries to this external database are sometimes taking a while to run. This lag is experienced through the browser.

Possible Solution

I want to use threading to eliminate the simulated hang to the browser. I have used the Thread class before and heard about ThreadPool. But, I just found BackgroundWorker in this post.

MSDN states:

The BackgroundWorker class allows you to run an operation on a separate, dedicated thread. Time-consuming operations like downloads and database transactions can cause your user interface (UI) to seem as though it has stopped responding while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, the BackgroundWorker class provides a convenient solution.

Is BackgroundWorker the way to go when handling long running queries?

What happens when 2 or more BackgroundWorker processes are ran simultaneously? Is it handled like a pool?

+1  A: 

Yes, BackgroundWorker can significantly simplify your threading code for long-running operations. The key is registering for the DoWork, ProgressChanged, and RunWorkerCompleted events. These help you avoid having to have a bunch of synchronization objects passed back and forth with the thread to try to determine the progress of the operation.

Also, I believe the progress events are called on the UI thread, avoiding the need for calls to Control.Invoke to update your UI.

To answer your last question, yes, threads are allocated from the .NET thread pool, so you while you may instantiate as many BackgroundWorker objects as you'd like, you can only run as many concurrent operations as the thread pool will allow.

mjmarsh
That's right - the progress and completed events are marshaled to the UI thread (well, whatever the current thread synchronization context says to do, but for winforms/wpf that's the UI thread) so you don't have to do it yourself.
James Manning
A: 

I had ran in similar situation with long running queries. I used the asynchronous invoke provided by delegates. You can use the BeginInvoke method of the delegate.

Yogendra
Both the asynchronous delegate invoking, and the background worker use the ThreadPool under the covers. If it's a simple background process that needs to run, and you don't need the added complexity of IAsyncResult, BackgroundWorker is a better choice IMO.
BFree
A: 

BackgroundWrokerks are just like any other threads, accept they can be killed or quit, w/out exiting the main thread and your application.

ThreadPool uses a pool of BackgroundWorkers. It is the preferred way of most multi threading scenarios because .net manages threads for you, and it re-uses them instead of creating new ones as needed which is a expensive process.

Such threading scenarios are great for processor intensive code.

For something like a query which happens externally, you also have the option of asynchronous data access. You can hand off the query request, and give it the name of your callback method, which will be called when query is finished and than do something with the result (i.e. update UI status or display returned data)..

.Net has inbuilt support for asynchronous data querying http://www.devx.com/dotnet/Article/26747

Sonic Soul
+1  A: 

If you're using .NET 4 (or can use the TPL backport from the Rx Framework), then one nice option is to use a Task created with the LongRunning hint.

This provides many options difficult to accomplish via the ThreadPool or BackgroundWorker, including allowing for continuations to be specified at creation time, as well as allowing for clean cancellation and exception/error handling.

Reed Copsey
Currently, built for .Net 3.5.
Eddie
I do like the typed return value for Task<TResult> though. Does beat out (object)DoWorkEventArgs.Result in BackgroundWorker.
Eddie
@Eddie: You can use the Rx Framework to get the TPL for .NET 3.5sp1. It's a much, much cleaner API than previous threading models, IMO.
Reed Copsey