0

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?

Community
  • 1
  • 1
Eddie
  • 5,050
  • 8
  • 37
  • 46
  • Sorry is this a desktop application or web application? – Darknight Jun 10 '10 at 21:20
  • 1
    @Eddie: C# doesn't support threads. You're asking about the .NET Framework, aren't you? – John Saunders Jun 10 '10 at 21:22
  • @John C# DOES support threading! – Darknight Jun 10 '10 at 21:23
  • The BackgroundWoker uses the .Net ThreadPool under the covers, so if you use two background workers, it's just like calling threadpool.queueuserworkitem twice. – BFree Jun 10 '10 at 21:29
  • @Eddie Careful. John is a stickler for that distinction. C# itself doesn't have a threading. The .net framework (meaning the `Thread` class) provides threading support. – Jason Webb Jun 10 '10 at 21:43
  • Well, if we're going to be sticklers :)... c# does not offer the ability to create a thread (that's in the .net runtime), the language DOES support threading (hence the lock statement). (and we might say, yes but that's just a wrapper around a Monitor, but it's still a statement that is recognized by the c# compiler, and it's only purpose is to support threading). If we're going to be distinctive :) – JMarsch Jun 10 '10 at 21:53
  • @JMarsch: I apologize. I forgot about the `lock` statement. I should have said that C# does not support the creation or management of threads, and only permits their control through the `lock` statement. – John Saunders Jun 10 '10 at 21:59
  • @Jason: the reason I'm a stickler here is that C# is not the only .NET language! VB.NET and F# are .NET languages from Microsoft that have precisely the same threading support as C# (none). All three depend on the .NET Framework for threading, and to exactly the same degree. – John Saunders Jun 10 '10 at 22:00
  • Yes, project is a C# .Net web application. – Eddie Jun 11 '10 at 12:23
  • @John Saunders: Thanks for the edits. Was in a rush when posting the question. – Eddie Jun 11 '10 at 12:26

4 Answers4

2

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.

Mike Marshall
  • 7,788
  • 4
  • 39
  • 63
  • 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 Jun 11 '10 at 05:06
1

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
  • 554,122
  • 78
  • 1,158
  • 1,373
0

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.

AlwaysAProgrammer
  • 2,927
  • 2
  • 31
  • 40
  • 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 Jun 10 '10 at 21:28
0

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
  • 23,855
  • 37
  • 130
  • 196