What is the best way to launch 10 threads like in a for loop for a process intensive method. A code example would be very helpful.
for (int i = 0; i<=10; i++) //10 threads are intended.
{
LongRunningMethod();
}
ThreadPool.QueueUserWorkItem
As mentioned in the other answers, you can use ThreadPool.QueueUserWorkItem to schedule your job on a thread in the thread pool or create a new explicit Thread instance for that work. You can read more about the various ways to create threads at the MSDN Threading Tutorial.
Which approach you use can have certain implications on the performance and behavior of your app and the CLR. For more details, read When to use thread pool in C#
Or if you don't want to use the thread pool, just create and start a new thread.
new Thread( delegate() { LongRunningMethod(); } ).Start();
Use Action as a delegate to create a new thread for each long running method call.
Action newThread = new Action(LongRunningMethod);
// Call Async which is a new thread
newThread.BeginInvoke(null, null);
Action with no template is only in .NET 3.5, for .NET 2.0 you have to declare a delegate
public delegate void NoParametersMethod();
NoParametersMethodnewThread = new NoParametersMethod(LongRunningMethod);
// Call Async which is a new thread
newThread.BeginInvoke(null, null);
The answers and comments here may seem a bit divided, this is because the first thing to do here is to check if your LongRunningMethod() is suited for the Threadpool. If it is then using the ThreadPool is the best choice (low overhead, some rudimentary loadbalancing).
Otherwise, use Thread and ThreadStart:
ThreadStart starter = new ThreadStart(LongRun);
for (int i = 1; i <= 10; i++) // 10 threads are intended, note the i=1
{
Thread t = new Thread(starter);
t.Start();
}
Note 1: that there also exists a ParameterizedThreadStart class.
Note 2: You can't scale this to i < 100 or something, you need to keep a lid on the max number of threads. The pool already does that.
From MSDN:
When Not to Use Thread Pool Threads
There are several scenarios in which it is appropriate to create and manage your own threads instead of using thread pool threads:
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.
Note that MSDN does not say what a 'long period of time' is. I'll take a stab at it and say that when your task takes >= 0.5 second you might start looking at separate threads. The overhead of creating a Thread becomes insignificant. But it depends on a lot of factors.
Something simple like this ...
var threads = new List<Thread>();
var numThreads = 10;
for( int i = 0; i < numThreads; i++ )
{
threads.Add( new Thread( () => DoWork() ) );
threads[i].Name = i.ToString();
threads[i].Start();
}
Related
This question already has answers here:
When does a multithreaded console application exit?
(2 answers)
Closed last year.
Sorry if my question seems naive. I'm new to C# and .Net, and still wrap my head around them.
I come from a Go-Lang background, and try to learn C#/.Net multithreading.
In Go the main thread will run and complete its logic regardless of other threads if no wait is used.
I thought it should be the same in C#, however, the code below allow all threads to run completely.
Which means Main thread waits other threads to complete, without using join() or any other wait techniques.
Could you please, let me know what I missed here or misunderstood.
namespace TestThread
{
internal class Program
{
static void Main(string[] args)
{
Thread T1 = new Thread(PrintY);
T1.Start();
// The following is the funtion of the Main thread.
for (int i = 0; i < 10; i++) Console.Write("x");
}
static void PrintY()
{
for (int i = 0; i < 100; i++)
{
Console.Write("Y");
Thread.Sleep(100);
}
}
}
}
The output is like the following:
xxxxxxxxxYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
I expected at most one Y in the results before the Main method finishes and therefore the process terminates. What is keeping the process alive when the main thread is completed?
When you are creating Thread via constructor by default it's Thread.IsBackground is set to false:
A thread is either a background thread or a foreground thread. Background threads are identical to foreground threads, except that background threads do not prevent a process from terminating. Once all foreground threads belonging to a process have terminated, the common language runtime ends the process. Any remaining background threads are stopped and do not complete.
And:
By default, the following threads execute in the foreground (that is, their IsBackground property returns false):
The primary thread (or main application thread).
All threads created by calling a Thread class constructor.
So it will prevent the app from terminating. If you want your threads to allow the application to terminate you can set this property to false:
Thread T1 = new Thread(PrintY);
T1.IsBackground = true;
...
Also note that manually creating threads is rarely needed operation in modern C#. After introduction of Task Parallel Library (TPL) usually Task APIs are used instead of directly manipulating the threads (_ = Task.Run(PrintY); for example can be used in this case).
I have a little c# app with multiple threads runing, but my main thread has to wait for all of threads to finish then it can do the rest.
problem now is that im using .join() for each thread, this seems wait for each thread to finish then it goes to next thread, which makes app not really multi-threading and take long time to finish.
so I wonder if there is any way I can get around this problem or just a way to check if there are no more threads is active.
thanks
If you're hanging on to the Thread object, you can use Thread.IsAlive.
Alternately, you might want to consider firing an event from your thread when it is done.
Thread.Join() doesn't mean your application isn't multithreaded - it tells the current thread to wait for the other thread to finish, which is exactly what you want.
Doing the following:
List<Thread> threads = new List<Thread>();
/** create each thread, Start() it, and add it to the list **/
foreach (Thread thread in threads)
{
thread.Join()
}
will continue to run the other threads, except the current/main thread (it will wait until the other threads are done).
Just use Thread.Join()
Ye, as said by Cuong Le, using Task Parallel Library would be much efficient.
However, you can Create a list of Threads and then check if they are alive or not.
var threadsList = new List<Thread>();
threadsList.Add(myThread); // to add
bool areDone = true;
foreach (Thread t in threadsList) {
if (t.IsAlive)
{
areDone = false;
break;
}
}
if (areDone)
{
// Everything is finished :O
}
Run multiple at same time but wanted to wait for all of them to finish, here's a way of doing the same with Parallel.ForEach:
var arrStr = new string[] {"1st", "2nd", "3rd"};
Parallel.ForEach<string>(arrStr, str =>
{
DoSomething(str); // your custom method you wanted to use
Debug.Print("Finished task for: " + str);
});
Debug.Print("All tasks finished");
That was the most simplest and efficient i guess it can go if in C# 4.0 if you want all tasks to run through same method
Try using BackgroundWorker
It raises an event in the main thread (RunWorkerCompleted) after its work is done
Here is one sample from previously answered question
https://stackoverflow.com/a/5551376/148697
I having problem managed thread parallel in console application.
I am running 10 threads parallel & all thread doing some specific task.
In case if any task is over/completed then doing stop/end thread and immediate I started new thread instance. I want 10 threads so anyone thread is going to stop/end then It generates new thread. but every time I want 10 threads in running mode in console application & It should be parallel work using C# console application.
How I can running 10 threads in C# console application?
At the end of each thread put a lock on some shared object (lock (obj) {}).
Then remove the current thread from a collection of threads you have.
If the collection.Count is less than 10 create a new one and put inside the collection.
Release the lock.
private List<Thread> threads = new List<Thread>();
private void ThreadFunction() {
// do something
// here before the lock
lock (threads) {
threads.Remove(Thread.CurrentThread);
if (thread.Count < 10) {
Thread t = new Thread(ThreadFunction);
threads.Add(t);
t.Start();
}
}
}
Be sure to catch all exception inside the thread or you code will fail when a thread exception happens. That is make sure that the lock part of the code is always called (except on a Thread abord exception but that will not matter).
But as stated I think you should use a ThreadPool for such a task...
The book on threads in .Net is: http://www.albahari.com/threading/
This alone will probably answer any questions you have.
Depending on what you are using these threads for (I am guessing that you may be talking about running transactions in the background) you may want to use BackgroundWorker.
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
BackgroundWorker lets you deal with Begin/End/Progress Events only, making debugging much less error prone.
I would like to start x number of threads from my .NET application, and I would like to keep track of them as I will need to terminate them manually or when my application closes my application later on.
Example ==> Start Thread Alpha, Start Thread Beta .. then at any point in my application I should be able to say Terminate Thread Beta ..
What is the best way to keep track of opened threads in .NET and what do I need to know ( an id ? ) about a thread to terminate it ?
You could save yourself the donkey work and use this Smart Thread Pool. It provides a unit of work system which allows you to query each thread's status at any point, and terminate them.
If that is too much bother, then as mentioned anIDictionary<string,Thread> is probably the simplest solution. Or even simpler is give each of your thread a name, and use an IList<Thread>:
public class MyThreadPool
{
private IList<Thread> _threads;
private readonly int MAX_THREADS = 25;
public MyThreadPool()
{
_threads = new List<Thread>();
}
public void LaunchThreads()
{
for (int i = 0; i < MAX_THREADS;i++)
{
Thread thread = new Thread(ThreadEntry);
thread.IsBackground = true;
thread.Name = string.Format("MyThread{0}",i);
_threads.Add(thread);
thread.Start();
}
}
public void KillThread(int index)
{
string id = string.Format("MyThread{0}",index);
foreach (Thread thread in _threads)
{
if (thread.Name == id)
thread.Abort();
}
}
void ThreadEntry()
{
}
}
You can of course get a lot more involved and complicated with it. If killing your threads isn't time sensitive (for example if you don't need to kill a thread in 3 seconds in a UI) then a Thread.Join() is a better practice.
And if you haven't already read it, then Jon Skeet has this good discussion and solution for the "don't use abort" advice that is common on SO.
You can create a Dictionary of threads and assign them id's, like:
Dictionary<string, Thread> threads = new Dictionary<string, Thread>();
for(int i = 0 ;i < numOfThreads;i++)
{
Thread thread = new Thread(new ThreadStart(MethodToExe));
thread.Name = threadName; //Any name you want to assign
thread.Start(); //If you wish to start them straight away and call MethodToExe
threads.Add(id, thread);
}
If you don't want to save threads against an Id you can use a list and later on just enumerate it to kill threads.
And when you wish to terminate them, you can abort them. Better have some condition in your MethodToExe that allows that method to leave allowing the thread to terminate gracefully. Something like:
void MethodToExe()
{
while(_isRunning)
{
//you code here//
if(!_isRunning)
{
break;
}
//you code here//
}
}
To abort you can enumerate the dictionary and call Thread.Abort(). Be ready to catch ThreadAbortException
I asked a similar questions and received a bunch of good answers: Shutting down a multithreaded application
Note: my question did not require a graceful exit, but people still recommended that I gracefully exit from the loop of each thread.
The main thing to remember is that if you want to avoid having your threads prevent your process from terminating you should set all your threads to background:
Thread thread = new Thread(new ThreadStart(testObject.RunLoop));
thread.IsBackground = true;
thread.start();
The preferred way to start and manage threads is in a ThreadPool, but just about any container out there can be used to keep a reference to your threads. Your threads should always have a flag that will tell them to terminate and they should continually check it.
Furthermore, for better control you can supply your threads with a CountdownLatch: whenever a thread is exiting its loop it will signal on a CountdownLatch. Your main thread will call the CountdownLatch.Wait() method and it will block until all the threads have signaled... this allows you to properly cleanup and ensures that all your threads have shutdown before you start cleaning up.
public class CountdownLatch
{
private int m_remain;
private EventWaitHandle m_event;
public CountdownLatch(int count)
{
Reset(count);
}
public void Reset(int count)
{
if (count < 0)
throw new ArgumentOutOfRangeException();
m_remain = count;
m_event = new ManualResetEvent(false);
if (m_remain == 0)
{
m_event.Set();
}
}
public void Signal()
{
// The last thread to signal also sets the event.
if (Interlocked.Decrement(ref m_remain) == 0)
m_event.Set();
}
public void Wait()
{
m_event.WaitOne();
}
}
It's also worthy to mention that the Thread.Abort() method does some strange things:
When a thread calls Abort on itself,
the effect is similar to throwing an
exception; the ThreadAbortException
happens immediately, and the result is
predictable. However, if one thread
calls Abort on another thread, the
abort interrupts whatever code is
running. There is also a chance that a
static constructor could be aborted.
In rare cases, this might prevent
instances of that class from being
created in that application domain. In
the .NET Framework versions 1.0 and
1.1, there is a chance the thread could abort while a finally block is
running, in which case the finally
block is aborted.
The thread that calls Abort might
block if the thread that is being
aborted is in a protected region of
code, such as a catch block, finally
block, or constrained execution
region. If the thread that calls Abort
holds a lock that the aborted thread
requires, a deadlock can occur.
After creating your thread, you can set it's Name property. Assuming you store it in some collection you can access it conveniently via LINQ in order to retrieve (and abort) it:
var myThread = (select thread from threads where thread.Name equals "myThread").FirstOrDefault();
if(myThread != null)
myThread.Abort();
Wow, there are so many answers..
You can simply use an array to hold the threads, this will only work if the access to the array will be sequantial, but if you'll have another thread accessing this array, you will need to synchronize access
You can use the thread pool, but the thread pool is very limited and can only hold fixed amount of threads.
As mentioned above, you can create you own thread pool, which in .NET v4 becomes much easier with the introduction of safe collections.
you can manage them by holding a list of mutex object which will determine when those threads should finish, the threads will query the mutex each time they run before doing anything else, and if its set, terminate, you can manage the mutes from anywhere, and since mutex are by defenition thread-safe, its fairly easy..
i can think of another 10 ways, but those seems to work. let me know if they dont fit your needs.
Depends on how sophisticated you need it to be. You could implement your own type of ThreadPool with helper methods etc. However, I think its as simple as just maintaining a list/array and adding/removing the threads to/from the collection accordingly.
You could also use a Dictionary collection and use your own type of particular key to retrieve them i.e. Guids/strings.
As you start each thread, put it's ManagedThreadId into a Dictionary as the key and the thread instance as the value. Use a callback from each thread to return its ManagedThreadId, which you can use to remove the thread from the Dictionary when it terminates. You can also walk the Dictionary to abort threads if needed. Make the threads background threads so that they terminate if your app terminates unexpectedly.
You can use a separate callback to signal threads to continue or halt, which reflects a flag set by your UI, for a graceful exit. You should also trap the ThreadAbortException in your threads so that you can do any cleanup if you have to abort threads instead.
I have a scenario when I start 3..10 threads with ThreadPool.
Each thread does its job and returns to the ThreadPool.
What are possible options to be notified in main thread when all background threads have finished?
Currently I'm using a homegrown method with incrementing a variable for each of created threads and decrementing it when a background thread is about to finish.
This works just fine, but I was curious if there are better options.
Decrementing a variable (between threads) is a little bit risky unless done with Interlocked.Decrement, but that approach should be fine if you have the last thread (i.e. when it gets to zero) raise an event. Note that it would have to be in a "finally" block to avoid losing it in the case of exceptions (plus you don't want to kill the process).
In "Parallel Extensions" (or with .NET 4.0), you might also look at the Parallel.ForEach options here... that might be another way of getting everything done as a block. Without having to watch them all manually.
Try this: https://bitbucket.org/nevdelap/poolguard
using (var poolGuard = new PoolGuard())
{
for (int i = 0; i < ...
{
ThreadPool.QueueUserWorkItem(ChildThread, poolGuard);
}
// Do stuff.
poolGuard.WaitOne();
// Do stuff that required the child threads to have ended.
void ChildThread(object state)
{
var poolGuard = state as PoolGuard;
if (poolGuard.TryEnter())
{
try
{
// Do stuff.
}
finally
{
poolGuard.Exit();
}
}
}
Multiple PoolGuards can be used in different ways to track when threads have ended, and handles threads that haven't started when the pool is already closed.
If its not more than 64 Threads to wait on, you can use the WaitHandle.WaitAll method like this:
List<WaitHandle> events = new List<WaitHandle>();
for (int i = 0; i < 64; i++)
{
ManualResetEvent mre = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(
delegate(object o)
{
Thread.Sleep(TimeSpan.FromMinutes(1));
((ManualResetEvent)o).Set();
},mre);
events.Add(mre);
}
WaitHandle.WaitAll(events.ToArray());
The execution will wait till all ManualResetEvents are set, alternatively, you may use WaitAny method.
The WaitAny and WaitAll methods will block the execution, but you can simply use the list, or a dictionary of ManualResetEvents linked to the task that is spawn for later determining if the thread is done though.
There's isn't a built-in way to do this at the moment - I find it one of the biggest pains about using pool threads.
As Marc says, this is the kind of stuff which is being fixed in Parallel Extensions / .NET 4.0.
Couldn't you give each thread a distinct ManualResetEvent and have each set the event when done. Then, in the main thread you can wait on all the events passed in.
Marc's solution is best if you just want to know when all the jobs are finished, and don't need finer info than that (as seems to be your case).
If you wanted some thread to spawn jobs, and some other thread to to receive the notifications, you could use WaitHandle. The code is much longer.
int length = 10;
ManualResetEvent[] waits = new ManualResetEvent[length];
for ( int i = 0; i < length; i++ ) {
waits[i] = new ManualResetEvent( false );
ThreadPool.QueueUserWorkItem( (obj) => {
try {
} finally {
waits[i].Set();
}
} );
}
for ( int i = 0; i < length; i++ ) {
if ( !waits[i].WaitOne() )
break;
}
The WaitOne method, as written, always returns true, but I have written it like that to make you remember that some overloads take a Timeout as an argument.
What about using Semaphore, and set a limit to it as much as your thread pool. Have a method to fetch a Semaphore, to be called when you start your thread, release it when your thread end and raise an event if you've taken up all the Semaphore.