Alternative to Threads

I've read that threads are very problematic. What alternatives are available? Something that handles blocking and stuff automatically?

A lot of people recommend the background worker, but I've no idea why.

Anyone care to explain "easy" alternatives? The user will be able to select the number of threads to use (depending on their speed needs and computer power).

Any ideas?

-------------Problems Reply------------

To summarize the problems with threads:

  • if threads share memory, you can get race conditions
  • if you avoid races by liberally using locks, you can get deadlocks (see the dining philosophers problem)

An example of a race: suppose two threads share access to some memory where a number is stored. Thread 1 reads from the memory address and stores it in a CPU register. Thread 2 does the same. Now thread 1 increments the number and writes it back to memory. Thread 2 then does the same. End result: the number was only incremented by 1, while both threads tried to increment it. The outcome of such interactions depend on timing. Worse, your code may seem to work bug-free but once in a blue moon the timing is wrong and bad things happen.

To avoid these problems, the answer is simple: avoid sharing writable memory. Instead, use message passing to communicate between threads. An extreme example is to put the threads in separate processes and communicate via TCP/IP connections or named pipes.

Another approach is to share only read-only data structures, which is why functional programming languages can work so well with multiple threads.

This is a bit higher-level answer, but it may be useful if you want to consider other alternatives to threads. Anyway, most of the answers discussed solutions based on threads (or thread pools) or maybe tasks from .NET 4.0, but there is one more alternative, which is called message-passing. This has been successfuly used in Erlang (a functional language used by Ericsson). Since functional programming is becoming more mainstream in these days (e.g. F#), I thought I could mention it. In genral:

  • Threads (or thread pools) can usually used when you have some relatively long-running computation. When it needs to share state with other threads, it gets tricky (you have to correctly use locks or other synchronization primitives).
  • Tasks (available in TPL in .NET 4.0) are very lightweight - you can split your program into thousands of tasks and then let the runtime run them (it will use optimal number of threads). If you can write your algorithm using tasks instead of threads, it sounds like a good idea - you can avoid some synchronization when you run computation using smaller steps.
  • Declarative approaches (PLINQ in .NET 4.0 is a great option) if you have some higher-level data processing operation that can be encoded using LINQ primitives, then you can use this technique. The runtime will automatically parallelize your code, because LINQ doesn't specify how exactly should it evaluate the results (you just say what results you want to get).
  • Message-passing allows you two write program as concurrently running processes that perform some (relatively simple) tasks and communicate by sending messages to each other. This is great, because you can share some state (send messages) without the usual synchronization issues (you just send a message, then do other thing or wait for messages). Here is a good introduction to message-passing in F# from Robert Pickering.

Note that the last three techniques are quite related to functional programming - in functional programming, you desing programs differently - as computations that return result (which makes it easier to use Tasks). You also often write declarative and higher-level code (which makes it easier to use Declarative approaches).

When it comes to actual implementation, F# has a wonderful message-passing library right in the core libraries. In C#, you can use Concurrency & Coordination Runtime, which feels a bit "hacky", but is probably quite powerful too (but may look too complicated).

Won't the parallel programming options in .Net 4 be an "easy" way to use threads? I'm not sure what I'd suggest for .Net 3.5 and earlier...

This MSDN link to the Parallel Computing Developer Center has links to lots of info on Parellel Programming including links to videos, etc.

I can recommend this project. Smart Thread Pool

Project Description Smart Thread Pool is a thread pool written in C#. It is far more advanced than the .NET built-in thread pool. Here is a list of the thread pool features:

  • The number of threads dynamically changes according to the workload on the threads in the pool.
  • Work items can return a value.
  • A work item can be cancelled.
  • The caller thread's context is used when the work item is executed (limited).
  • Usage of minimum number of Win32 event handles, so the handle count of the application won't explode.
  • The caller can wait for multiple or all the work items to complete.
  • Work item can have a PostExecute callback, which is called as soon the work item is completed.
  • The state object, that accompanies the work item, can be disposed automatically.
  • Work item exceptions are sent back to the caller.
  • Work items have priority.
  • Work items group.
  • The caller can suspend the start of a thread pool and work items group.
  • Threads have priority.
  • Can run COM objects that have single threaded apartment.
  • Support Action and Func delegates.
  • Support for WindowsCE (limited)
  • The MaxThreads and MinThreads can be changed at run time.
  • Cancel behavior is imporved.

"Problematic" is not the word I would use to describe working with threads. "Tedious" is a more appropriate description.

If you are new to threaded programming, I would suggest reading this thread as a starting point. It is by no means exhaustive but has some good introductory information. From there, I would continue to scour this website and other programming sites for information related to specific threading questions you may have.

As for specific threading options in C#, here's some suggestions on when to use each one.

  • Use BackgroundWorker if you have a single task that runs in the background and needs to interact with the UI. The task of marshalling data and method calls to the UI thread are handled automatically through its event-based model. Avoid BackgroundWorker if (1) your assembly does not already reference the System.Windows.Form assembly, (2) you need the thread to be a foreground thread, or (3) you need to manipulate the thread priority.
  • Use a ThreadPool thread when efficiency is desired. The ThreadPool helps avoid the overhead associated with creating, starting, and stopping threads. Avoid using the ThreadPool if (1) the task runs for the lifetime of your application, (2) you need the thread to be a foreground thread, (3) you need to manipulate the thread priority, or (4) you need the thread to have a fixed identity (aborting, suspending, discovering).
  • Use the Thread class for long-running tasks and when you require features offered by a formal threading model, e.g., choosing between foreground and background threads, tweaking the thread priority, fine-grained control over thread execution, etc.

Any time you introduce multiple threads, each running at once, you open up the potential for race conditions. To avoid these, you tend to need to add synchronization, which adds complexity, as well as the potential for deadlocks.

Many tools make this easier. .NET has quite a few classes specifically meant to ease the pain of dealing with multiple threads, including the BackgroundWorker class, which makes running background work and interacting with a user interface much simpler.

.NET 4 is going to do a lot to ease this even more. The Task Parallel Library and PLINQ dramatically ease working with multiple threads.

As for your last comment:

The user will be able to select the number of threads to use (depending on their speed needs and computer power).

Most of the routines in .NET are built upon the ThreadPool. In .NET 4, when using the TPL, the work load will actually scale at runtime, for you, eliminating the burden of having to specify the number of threads to use. However, there are ways to do this now.

Currently, you can use ThreadPool.SetMaxThreads to help limit the number of threads generated. In TPL, you can specify ParallelOptions.MaxDegreesOfParallelism, and pass an instance of the ParallelOptions into your routine to control this. The default behavior scales up with more threads as you add more processing cores, which is usually the best behavior in any case.

Threads are not problematic if you understand what causes problems with them.

For ex. if you avoid statics, you know which API's to use (e.g. use synchronized streams), you will avoid many of the issues that come up for their bad utilization.

If threading is a problem (this can happen if you have unsafe/unmanaged 3rd party dll's that cannot support multithreading. In this can an option is to create a meachism to queue the operations. ie store the parameters of the action to a database and just run through them one at a time. This can be done in a windows service. Obviously this will take longer but in some cases is the only option.

Threads are indispensable tools for solving many problems, and it behooves the maturing developer to know how to effectively use them. But like many tools, they can cause some very difficult-to-find bugs.

Don't shy away from some so useful just because it can cause problems, instead study and practice until you become the go-to guy for multi-threaded apps.

A great place to start is Joe Albahari's article: http://www.albahari.com/threading/.

Category:c# Views:1 Time:2010-02-05

Related post

  • Alternative to thread for small tasks without freezing the GUI 2011-01-25

    I'm writing a small application, composed by a gui and a couple of buttons. When the user clicks one of them, the program must download a webpage, do a couple of matching and return a value to the gui. The question is, I must start a new thread every

  • Alternative to threads for implementing massive parallel calculation engine in c# or java? 2012-04-29

    Suppose there is a need for building a spreadsheet-like engine that needs to be ultra fast, each cell dependencies could be on parallel calculation branch. Could thread be created for each parallel branch ? Isn't thread costfull in term of memory. Ea

  • Alternatives to Thread.Sleep() for simulating pauses 2009-09-21

    So Thread.Sleep() is bad (http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx). Is there any recommended alternative to simulating a pause in execution of a program? Eg a loop? Although I s

  • Alternative to Thread.Sleep() before socket read 2011-01-27

    I'm using this FtpClient library to connect to mainframe from WinForms application. I'm using thread.Sleep for the thread to wait for the response before it starts reading, otherwise it freezes. Is there an alternative to do this? public void Login()

  • Alternatives to Thread.Sleep() 2011-03-24

    Every N minutes we want to run through a list of tasks. So we've created a task executor with a do { DoWork(); }while(!stopRequested) Now we want to have a pause between work cycles. Everyone seems to think Thread.Sleep() is the devil. I've seen ment

  • C# - Alternative to Thread.Sleep? 2011-03-27

    I'm doing all this in C#, in Visual Studio 2008. I want to slow down the work of my algorithm so that the user can watch it's work. There is a periodic change visible at the GUI so I added "thread.sleep" after every instance. Problem is that "thread.

  • Thread Safe Alternative to Thread.Sleep that allows browser activity in c# 2011-11-30

    I need a simple wait function that allows browser events to process and is thread-safe. A collegue said never to use DoEvents when working with multiple threads. I notice that when I use Thread.Sleep(10000); my browser activity pauses until the sleep

  • Java - alternative to thread.sleep 2012-02-04

    I have a requirement to pause a while loop for a specific number of milliseconds. I have tried using Thread.sleep(duration) but it is not accurate, especially in a looping scenario. Millisecond accuracy is important in my program. Here is the algorit

  • Alternative to Thread.Suspend() method 2012-04-18

    Thread.Suspend() method is obsolete as you know. I want to suspend thread immidiately when button click event comes. I used Thread.Suspend() and it works perfect but everyone suggest that using Thread.Suspend() method is not a good method to suspend

  • Alternative to Thread.Sleep in C#? 2012-02-02

    I have a code which when run, it executes series of lines in sequence. I would like to add a pause in between. Currently, I have it like this //do work Thread.Sleep(10800000); //do work This however freezes the software, and I think it's because slee

  • Java Concurrency: Alternative to Multi Threading (working with non thread safe environment) 2012-02-16

    I am working with a 3rd party proprietary library (no source code) which creates instances of a non thread safe component. Does this mean that I shouldn't use multiple threads to run jobs in parallel? Running each job in it's own JVM crossed my mind

  • Re-creating threading and concurrency knowledge in increasingly popular languages 2009-01-13

    I am primarily a Java developer, and I've been reading a lot of in-depth work on threads and concurrency. Many very smart people (Doug Lea, Brian Goetz, etc) have authored books on these topics and made contributions to new concurrency libraries for

  • How independent are threads inside the same process? 2009-01-22

    Now, this might be a very newbie question, but I don't really have experience with multithreaded programming and I haven't fully understood how threads work compared to processes. When a process on my machine hangs, say it's waiting for some IO that

  • How do I safely populate an array from one thread while reading it in another in Objective-C? 2009-06-07

    First off I'm not that familiar with using threads and i'm learning on the fly. I have an array that is being used in thread a and being populated in thread b. What I want to do is find the best practice for waiting for the array to be populated from

  • Why might threads be considered "evil"? 2009-07-28

    I was reading the SQLite FAQ, and came upon this passage: Threads are evil. Avoid them. I don't quite understand the statement "Thread are evil". If that is true, then what is the alternative? My superficial understanding of threads is: Threads make

  • Is LWP::UserAgent not thread-safe? 2009-12-03

    I'm running 40-or-so threads with the following subroutine: my $app = shift; my $ua = LWP::UserAgent->new(); $ua->timeout(5); my $response = $ua->get($$app{'watch_url'}); my $new_md5; if ($response->is_success()) { $new_md5 = md5_hex($res

  • Thread.currentThread().sleep(time) v/s Thread.sleep(time); 2010-07-24

    Possible Duplicate: Java: Thread.currentThread().sleep(x) vs. Thread.sleep(x) whats the difference between... Thread.currentThread().sleep(time) and Thread.sleep(time); one more thing is there anyother method by which i can delay in program without u

  • How is Node.js inherently faster when it still relies on Threads internally? 2010-09-02

    I just watched the following video: Introduction to Node.js and still don't understand how you get the speed benefits. Mainly, at one point Ryan Dahl (Node.js' creator) says that Node.js is event-loop based instead of thread-based. Threads are expens

  • measure time .net thread spent waiting for IO 2011-01-25

    This is a continuation to How much time spent in a .NET Thread? I know how I can measure cpu time of a thread (http://www.codeproject.com/KB/dotnet/ExecutionStopwatch.aspx), but I don't know how to measure IO wait of a thread. Thread waits for IO, ge

Copyright (C) dskims.com, All Rights Reserved.

processed in 0.159 (s). 11 q(s)