.NET threading solution for long queries - c#

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?

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.

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.

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.

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

Related

.NET async framework - is there a limitation with thread-local data

I am looking to write a Windows Service that will start various "jobs".
Each "job" will:
be distinct in what it accomplishes
run for the lifetime of the Service, so "long running". Typically, a job will get 10 tasks from the database and process them, then sleep, and then repeat this cycle again and again.
Share the same "context". The application will be loosely coupled and call an IoC to get classes. It will also store some data on this context too
I need each job to be able to run in parallel and effectively run as separate programs.
My first thought was to create one thread per job. This is okay but has the drawback that a ManualResetEvent stops the thread in its tracks, and the Abort doesn't allow much chance for the Thread to exit in a graceful manner.
I then explored some of the new async framework in .NET 4.5 and boy does it seem to simplify coding.
However, whilst some of the data held on the context may be freely shared between each job, some can not: so each job requires it's own copy of certain data.
I attempted to solve this using ThreadLocal<T> properties. However, whilst this works fine for a specific thread that I've created, this doesn't work for the async methods. The thread that starts an async method is often not the thread that finishes the method, particularly when the method uses "await".
So, what is the preferred pattern for what I am attempting to accomplish?
FYI: Albahari's posting was a great help.

Which threads work method I need to use?

I have audio player application (c# .NET 4.0 WPF) that gets an audio-stream from the web and plays it. The app also displays waveforms and spectrums and saves the audio to local disk. It also does a few more things.
My quetion is when I recive a new byte packet from the web and I need to play them (and maybe write them to local disk etc.), do I need use threads? I try to do all the things with the main thread and it seems to work well.
I can work with threadpool for every bytes packet that I received in my connection. Would this be a reasonable approach?
For this you can use the Task Parallel Library (TPL). The Task Parallel Library (TPL) is a set of public types and APIs in the System.Threading and System.Threading.Tasks namespaces in the .NET Framework version 4. The purpose of the TPL is to make developers more productive by simplifying the process of adding parallelism and concurrency to applications. The TPL scales the degree of concurrency dynamically to most efficiently use all the processors that are available. In addition, the TPL handles the partitioning of the work, the scheduling of threads on the ThreadPool, cancellation support, state management, and other low-level details.
Another option (if the operations you were performing were sufficiently long running) is the BackgroundWorker class. The BackgroundWorker component gives you the ability to execute time-consuming operations asynchronously ("in the background"), on a thread different from your application's main UI thread. To use a BackgroundWorker, you simply tell it what time-consuming worker method to execute in the background, and then you call the RunWorkerAsync method. Your calling thread continues to run normally while the worker method runs asynchronously. When the method is finished, the BackgroundWorker alerts the calling thread by firing the RunWorkerCompleted event, which optionally contains the results of the operation. This may not be the best option for you if you have many operations to undertake sequentially.
The next alternative that has been largely replaced by the TPL, is the Thread Class. This is not so easy to use at the TPL and you can do everything using the TPL as you can using the Thread Class (well almost) and the TPL is much more user friendly.
I hope this helps.
I suggest using 2 threads: in one you are downloading packets from web and putting them in queue(it can be UI thread if you are using async download operation) and in another thread you are analyzing queue and processing packets from it.

Background Threads in Windows Phone

So far during my experience in Windows Phone 7 application development I notices there are different ways to runs an action in an asynchronous thread.
System.Threading.Thread
System.ComponentModel.BackgroundWorker
System.Threading.ThreadPool.QueueUserWorkItem()
I couldn't see any tangible difference between these methods (other than that the first two are more traceable).
Is there any thing you guys consider before using any of these methods? Which one would you prefer and why?
The question is kinda answered but the answers are a little short on detail (IMO).
Lets take each in turn.
System.Threading.Thread
All the threads (in the CLR anyway) are ultimately represented by this class. However you probably included this to query when we might want to create an instance ourselves.
The answer is rarely. Ordinarily the day-to-day workhorse for dispatching background tasks is the Threadpool. However there are some circumstances where we would want to create our own thread. Typically such a thread would live for most of the app runtime. It would spend most of its life in blocked on some wait handle. Occasionally we signal this handle and it comes alive to do something important but then it goes back to sleep. We don't use a Threadpool work item for this because we do not countenance the idea that it may queue up behind a large set of outstanding tasks some of which may themselves (perhaps inadverently) be blocked on some other wait.
System.ComponentModel.BackgroundWorker
This is friendly class wrapper around the a ThreadPool work item. This class only to the UI oriented developer who occasionally needs to use a background thread. Its events being dispatched on the UI thread makes it easy to consume.
System.Threading.ThreadPool.QueueUserWorkItem
This the day-to-day workhorse when you have some work you want doing on a background thread. This eliminates the expense of allocating and deallocating individual threads to perform some task. It limits the number of thread instances to prevent too much of the available resources being gobbled up by too many operations try to run in parallel.
The QueueUserWorkItem is my prefered option for invoking background operations.
It arguably depends on what you are trying to do, you have listed 3 very different threading models.
Basic threading
Designed for applications with a seperate UI thread.
Managed thread pool
Have you read MSDN etc...
http://www.albahari.com/threadin
Http://msdn.microsoft.com/en-us/library/aa645740(v=vs.71).aspx
You don't state "what for", but
Basic Thread - quite expensive, not for small jobs
Backgroundworker - mostly for UI + Progressbar work
ThreadPool - for small independent jobs
I think the TPL is not supported in SL, which is a pity.
The background worker tends to be better to use when your UI needs to be update as your thread progresses because it handles invoking the call back functions (such as the OnProgress callback) on the UI thread rather than the background thread. The other two don't do this work. It is up to you to do it.

Thread.Start() versus ThreadPool.QueueUserWorkItem()

The Microsoft .NET Base Class Library provides several ways to create a thread and start it. Basically the invocation is very similar to every other one providing the same kind of service: create an object representing an execution flow (or more), assign it a delegate representing the execution flow to execute and, eventually, depending on delegate signature, an object as a parameter.
Well, there are two approaches (essentially):
1) Using the System.Threading.Thread class.
Thread curr = new Thread(myfunction); /* In a class, myfunction is a void taking an object */
curr.Start(new Object()); /* Or something else to be downcast */
2) Using the System.Threading.ThreadPool class.
ThreadPool.QueueUserWorkItem(myfunction, new Object()); /* Same philosophy here */
Are there any special reasons why I should use 1) or 2)?
Performance reasons?
Patterns?
What is the best approach?
I have a feeling that the answer is: "Depend by the situation". Could you please list some situations where one approach is better than another?
Starting a new thread can be a very expensive operation. The thread pool reuses threads and thus amortizes the cost. Unless you need a dedicated thread, the thread pool is the recommended way to go. By using a dedicated thread you have more control over thread specific attributes such as priority, culture and so forth. Also, you should not do long running tasks on the thread pool as it will force the pool to spawn additional threads.
In addition to the options you mention .NET 4 offers some great abstractions for concurrency. Check out the Task and Parallel classes as well as all the new PLINQ methods.
The Managed Thread Pool has some very good guidelines on when NOT to use the thread pool.
In my experience, you want to create your own thread when you need a persistent, dedicated, long-running thread. For everything else, use asynchronous delegates or something like QueueUserWorkItem, BackgroundWorker, or the Task-related features of .NET 4.0.
Threads in ThreadPool are background threads;
All threads created and started by a new Thread object are foreground threads.
A background thread does not keep the managed execution environment running.
refer to http://msdn.microsoft.com/en-us/library/h339syd0.aspx for more.
In .NET 4.5.2 they added a new method: HostingEnvironment.QueueBackgroundWorkItem.
This appears to be an alternative to ThreadPool.QueueUserWorkItem. Both behave similarly, but there are some nice benefits to using the new method when working in ASP.NET:
The HostingEnvironment.QueueBackgroundWorkItem method lets you
schedule small background work items. ASP.NET tracks these items and
prevents IIS from abruptly terminating the worker process until all
background work items have completed. This method can't be called
outside an ASP.NET managed app domain.
Using the ThreadPool, you have less control of the threading system. This is a trade off to simplify the process for you. If you have all that you need from the ThreadPool, you should feel free to utilize it. If you need more control of the threads, then you need to of course use the Thread classes.
ThreadPool.QueueUserWorkItem() is basically for fire-and-forget scenarios, when application doesn't depend on whether operations will finish or not.
Use classic threads for fine-grained control.
You should use ThreadPool.QueueUserWorkItem except in cases of:
You require a foreground thread.
You require a thread to have a particular priority.
You have tasks that cause the thread to block for long periods of
time. The thread pool has a maximum number of threads, so a large
number of blocked thread pool threads might prevent tasks from
starting.
You need to place threads into a single-threaded apartment. All
ThreadPool threads are in the multithreaded apartment.
You need to have a stable identity associated with the thread, or to
dedicate a thread to a task.
Reference link.

Synchronous work in a BackgroundWorker

My application performs time consuming work independently on several files. I created a BackgroundWorker to pass the work off to on each file, but it appears the backgroundworker is only capable of performing asynchronous work. Is it possible to do several asynchronous tasks in unison with it, or is there a similar object for performing synchronous operations?
The background worker is usually used to update the UI and/or to pass off work so you don't freeze the UI when a long running process takes place. This means that you "pass" the background worker process the "file work" and then use a callback to update the UI(usually) all during which your APP remains responsive.
If the items are independent then you might want to spool up a few threads to split the work. Again, if I am understanding you correctly. If I am then you might want to look at Jon Skeet's threading article.
While you can use the BackgroundWorker, I think you should simply spin off a few threads to do the work. One thread (probably the main thread) will create and start these worker threads and then perform a Join on all the workers in order to wait for processing to complete.
Alternatively, have a look a the Parallel Extensions for .Net if you are using .Net 3.5. The Task object from that library is probably perfect for your situation.
You can do multiple aynchronous tasks by creating more then one BackgroundWorker object in your code. We created a JobPool class that created a number of BackgroundWorker objects to run so that we could control the total number running at any one time. But if there are just a few files you will be processing this wouldbe overkill.

Categories