I have a multithread application. I want only one thread to execute my function and other threads to pass it while my function executing. How can I do this?
My method is something like:
public void setOutput(int value)
{
try
{
GPOs gpos = reader.Config.GPO;
gpos[1].PortState = GPOs.GPO_PORT_STATE.TRUE;
gpos[2].PortState = GPOs.GPO_PORT_STATE.TRUE;
Thread.Sleep(WAIT);
gpos[1].PortState = GPOs.GPO_PORT_STATE.FALSE;
gpos[2].PortState = GPOs.GPO_PORT_STATE.FALSE;
}
catch (Exception ex)
{
logger.Error("An Exception occure while setting GPO to " + value + " " + ex.Message);
}
}
You can use a lock object in combination with Monitor.TryEnter.
private Object outputLock = new Object();
public void setOutput(int value)
{
if Monitor.TryEnter(outputLock)
{
try
{
.... your code in here
}
finally
{
Monitor.Exit(outputLock);
}
}
}
Only one thread at at time will be allowed into the Monitor.TryEnter block. If a thread arrives here while another thread is inside, then Monitor.TryEnter returns false.
You can use a Mutex
using System;
using System.Threading;
class Test
{
// Create a new Mutex. The creating thread does not own the
// Mutex.
private static Mutex mut = new Mutex();
private const int numIterations = 1;
private const int numThreads = 3;
static void Main()
{
// Create the threads that will use the protected resource.
for(int i = 0; i < numThreads; i++)
{
Thread myThread = new Thread(new ThreadStart(MyThreadProc));
myThread.Name = String.Format("Thread{0}", i + 1);
myThread.Start();
}
// The main thread exits, but the application continues to
// run until all foreground threads have exited.
}
private static void MyThreadProc()
{
for(int i = 0; i < numIterations; i++)
{
UseResource();
}
}
// This method represents a resource that must be synchronized
// so that only one thread at a time can enter.
private static void UseResource()
{
// Wait until it is safe to enter.
mut.WaitOne();
Console.WriteLine("{0} has entered the protected area",
Thread.CurrentThread.Name);
// Place code to access non-reentrant resources here.
// Simulate some work.
Thread.Sleep(500);
Console.WriteLine("{0} is leaving the protected area\r\n",
Thread.CurrentThread.Name);
// Release the Mutex.
mut.ReleaseMutex();
}
}
the accepted answer (https://stackoverflow.com/a/10753349/1606741 as of writing) is right, but I think using https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement is clearer and does basically the same.
One thread at a time can execute the block
private object once = new object();
public void setOutput(int value)
{
lock (once)
{
try
{
GPOs gpos = reader.Config.GPO;
gpos[1].PortState = GPOs.GPO_PORT_STATE.TRUE;
gpos[2].PortState = GPOs.GPO_PORT_STATE.TRUE;
Thread.Sleep(WAIT);
gpos[1].PortState = GPOs.GPO_PORT_STATE.FALSE;
gpos[2].PortState = GPOs.GPO_PORT_STATE.FALSE;
}
catch (Exception ex)
{
logger.Error("An Exception occure while setting GPO to " + value + " " + ex.Message);
}
}
}
You can give a name to your threads and check the name in the method
What about this solution:
private AutoResetEvent are = new AutoResetEvent();
public void setOutput(int value)
{
// Do not wait (block) == wait 0ms
if(are.WaitOne(0))
{
try
{
// Put your code here
}
finally
{
are.Set()
}
}
}
It seems be easier (cheaper) than Monitor with lock object, but maybe not so clear.
Related
I am new to threading concept, using threading first time in my application. One of my application processing multiple data, without threading it is taking approx 2 minutes while with help of threading it is taking just 25 seconds, but i want notification when all threads finishes work.
private int z = 0 ;
startfunction()
{
z= 250;
start1step(z);
}
private void start1step(int i)
{
if (i < 0)
return;
else
{
Thread thread = new Thread(new ThreadStart(WorkThreadFunction));
thread.Start();
start1step( --i);
}
}
public void WorkThreadFunction( )
{
try
{
int x = z ;
z-- ;
// do some background work
if(x ==0)
MessageBox.Show("All Thread finished");
}
catch
{
//
}
}
Above sample code is working perfectly except that notification part, I want notification when all threads finishes background work. There is one last step left which sums up work finished by all these threads.
Please help
There are lots of ways to do this. I would say the two most convenient methods that remain similar to your current implementation involve using a CountDownEvent or switching to the Task class for your threading. A third method involves using the Parallel.ForEach() method, and that might actually suit your specific scenario better.
CountDownEvent looks like this:
CountDownEvent countDown = new CountDownEvent(250);
startfunction()
{
countDown.Reset();
start1step(250);
countDown.Wait();
}
private void start1step(int i)
{
while (i-- > 0)
{
new Thread(WorkThreadFunction, i).Start();
}
}
public void WorkThreadFunction(object o)
{
int x = (int)o;
try
{
// do some background work
}
catch
{
//
}
finally
{
countDown.Signal();
}
}
Task looks like this:
startfunction()
{
Task[] tasks = new Task[250];
start1step(tasks);
Task.WaitAll(tasks);
}
private void start1step(Task[] tasks)
{
for (int i = 0; i < tasks.Length; i++)
{
int taskParam = i;
tasks[i] = Task.Run(() => WorkThreadFunction(taskParam));
}
}
public void WorkThreadFunction(int x)
{
try
{
// do some background work
}
catch
{
//
}
}
Parallel.ForEach() looks like this:
startfunction()
{
Parallel.ForEach(Enumerable.Range(0, 250), i => WorkThreadFunction(i));
}
public void WorkThreadFunction(int x)
{
try
{
// do some background work
}
catch
{
//
}
}
In your main thread you can do something like this...
List<Thread> threads = new List<Thread>();
// CREATE THREADS and add them to the list of threads
while (threads.Any(x => x.IsAlive))
{
Thread.Sleep(500);
}
Console.WriteLine("done");
Essentially, keep track of the threads and check their status every now and then in a way that doesn't block the main thread.
I am building a small application simulating a horse race in order to gain some basic skill in working with threads.
My code contains this loop:
for (int i = 0; i < numberOfHorses; i++)
{
horsesThreads[i] = new Thread(horsesTypes[i].Race);
horsesThreads[i].Start(100);
}
In order to keep the race 'fair', I've been looking for a way to make all newly created threads wait until the rest of the new threads are set, and only then launch all of them to start running their methods (Please note that I understand that technically the threads can't be launched at the 'same time')
So basically, I am looking for something like this:
for (int i = 0; i < numberOfHorses; i++)
{
horsesThreads[i] = new Thread(horsesTypes[i].Race);
}
Monitor.LaunchThreads(horsesThreads);
Threading does not promise fairness or deterministic results, so it's not a good way to simulate a race.
Having said that, there are some sync objects that might do what you ask. I think the Barrier class (Fx 4+) is what you want.
The Barrier class is designed to support this.
Here's an example:
using System;
using System.Threading;
namespace Demo
{
class Program
{
private void run()
{
int numberOfHorses = 12;
// Use a barrier with a participant count that is one more than the
// the number of threads. The extra one is for the main thread,
// which is used to signal the start of the race.
using (Barrier barrier = new Barrier(numberOfHorses + 1))
{
var horsesThreads = new Thread[numberOfHorses];
for (int i = 0; i < numberOfHorses; i++)
{
int horseNumber = i;
horsesThreads[i] = new Thread(() => runRace(horseNumber, barrier));
horsesThreads[i].Start();
}
Console.WriteLine("Press <RETURN> to start the race!");
Console.ReadLine();
// Signals the start of the race. None of the threads that called
// SignalAndWait() will return from the call until *all* the
// participants have signalled the barrier.
barrier.SignalAndWait();
Console.WriteLine("Race started!");
Console.ReadLine();
}
}
private static void runRace(int horseNumber, Barrier barrier)
{
Console.WriteLine("Horse " + horseNumber + " is waiting to start.");
barrier.SignalAndWait();
Console.WriteLine("Horse " + horseNumber + " has started.");
}
private static void Main()
{
new Program().run();
}
}
}
[EDIT] I just noticed that Henk already mentioned Barrier, but I'll leave this answer here because it has some sample code.
I'd be looking at a ManualResetEvent as a gate; inside the Thread, decrement a counter; if it is still non-zero, wait on the gate; otherwise, open the gate. Basically:
using System;
using System.Threading;
class Program
{
static void Main()
{
ManualResetEvent gate = new ManualResetEvent(false);
int numberOfThreads = 10, pending = numberOfThreads;
Thread[] threads = new Thread[numberOfThreads];
ParameterizedThreadStart work = name =>
{
Console.WriteLine("{0} approaches the tape", name);
if (Interlocked.Decrement(ref pending) == 0)
{
Console.WriteLine("And they're off!");
gate.Set();
}
else gate.WaitOne();
Race();
Console.WriteLine("{0} crosses the line", name);
};
for (int i = 0; i < numberOfThreads; i++)
{
threads[i] = new Thread(work);
threads[i].Start(i);
}
for (int i = 0; i < numberOfThreads; i++)
{
threads[i].Join();
}
Console.WriteLine("all done");
}
static readonly Random rand = new Random();
static void Race()
{
int time;
lock (rand)
{
time = rand.Next(500,1000);
}
Thread.Sleep(time);
}
}
So according to MSDN, and many other places I've read, they use a semaphore and block within the individual threads, like so:
private static Semaphore _pool;
public static void Main()
{
_pool = new Semaphore(0, 3);
for(int i = 1; i <= 1000; i++)
{
Thread t = new Thread(new ParameterizedThreadStart(Worker));
t.Start(i);
}
}
private static void Worker(object num)
{
try
{
_pool.WaitOne();
// do a long process here
}
finally
{
_pool.Release();
}
}
Wouldn't it make more sense to block the process so that you don't create potentially 1000s of threads all at once depending on the number of iterations in Main()? For example:
private static Semaphore _pool;
public static void Main()
{
_pool = new Semaphore(0, 3);
for(int i = 1; i <= 1000; i++)
{
_pool.WaitOne(); // wait for semaphore release here
Thread t = new Thread(new ParameterizedThreadStart(Worker));
t.Start(i);
}
}
private static void Worker(object num)
{
try
{
// do a long process here
}
finally
{
_pool.Release();
}
}
Maybe both ways are not wrong and it depends on the situation? Or there is a better way to do this once there are a lot of iterations?
Edit: This is a windows service, so I'm not blocking the UI thread.
The reason you would normally do it inside the thread is you want to make that exclusive section as small as possible. You don't need the entire thread synchronized, only where that thread accesses the shared resource.
So a more realistic version of Worker is
private static void Worker(object num)
{
//Do a bunch of work that can happen in parallel
try
{
_pool.WaitOne();
// do a small amount of work that can only happen in 3 threads at once
}
finally
{
_pool.Release();
}
//Do a bunch more work that can happen in parallel
}
(P.S. If you are doing something that uses 1000 threads, you are doing something wrong. You should likely rather be using a ThreadPool or Tasks for many short-lived workloads or make each thread do more work.)
Here is how to do it with Parallel.ForEach
private static BlockingCollection<int> _pool;
public static void Main()
{
_pool = new BlockingCollection<int>();
Task.Run(() => //This is run in another thread so it shows data is being taken out and put in at the same time
{
for(int i = 1; i <= 1000; i++)
{
_pool.Add(i);
}
_pool.CompleteAdding(); //Lets the foreach know no new items will be showing up.
});
//This will work on the items in _pool, if there is no items in the collection it will block till CompleteAdding() is called.
Parallel.ForEach(_pool.GetConsumingEnumerable(), new ParallelOptions {MaxDegreeOfParallelism = 3}, Worker);
}
private static void Worker(int num)
{
// do a long process here
}
Following is the code that I use. The main thread waits for Threadpool threads to execute. I use AutoResetEvent (WaitHandle), but I am really surprised that I am way off the mark, as the code doesn't behave as expected.
I have two concentric for loops, where Threadpool is in the inner loop and it is expected that for each iteration of the outer loop, all the inner loop values should be processed. Main thread is made to wait using AutoResetEvent WaitOne call just outside inner loop, a static variable which is reset on every iteration of the outerloop to the max value of the inner loop, and is decremented using Interlock in the method call on Threadpool thread is used to call the Set for the AutoResetEvent. However, even when I expect the static variable to show the value 0 after every inner loop, it doesn't. What is the issue in my code and what are better options for me to accomplish the task? In fact, due to the mix up of the values, the main thread doesn't really seem to be waiting for the Threadpool threads.
using System;
using System.Threading;
namespace TestThreads
{
class Program
{
private static int threadingCounter = 0;
private static readonly object lockThreads = new Object();
private AutoResetEvent areSync = new AutoResetEvent(true);
// <param name="args"></param>
static void Main(string[] args)
{
Program myProgram = new Program();
try
{
try
{
for (int outer = 0; outer < 1000; outer++)
{
threadingCounter = 500;
try
{
for (int inner = 0; inner < 500; inner++)
{
ThreadPool.QueueUserWorkItem(new
WaitCallback(myProgram.ThreadCall), inner);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
finally
{
myProgram.areSync.WaitOne();
}
if(threadingCounter != 0)
Console.WriteLine("In Loop1, Thread Counter :: " +
threadingCounter);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
}
catch(Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
finally
{
threadingCounter = 0;
if (myProgram.areSync != null)
{
myProgram.areSync.Dispose();
myProgram.areSync = null;
}
}
}
public void ThreadCall(object state)
{
try
{
int inner = (int)state;
Thread.Sleep(1);
}
catch (Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
finally
{
Interlocked.Decrement(ref threadingCounter);
if (threadingCounter <= 0)
areSync.Set();
}
}
}
}
You have initialized AutoResetEvent with initial state as signaled(true) which will allow first call to
myProgram.areSync.WaitOne();
to continue without blocking, so it continues to outer loop and Queues execution to Threadpool again, hence the results are messed up. it is very clear.
update your code to
private AutoResetEvent areSync = new AutoResetEvent(false);
for expected results. hope this helps
I would refactor this using something like this. This assumes you want to do something in background threads in your inner loop, finish each of those before proceeding with your next outer loop, avoid messy exception handling while still capturing the exceptions that occurred during processing so that you can deal with those exceptions after processing is complete for both inner and outer loop.
// track exceptions that occurred in loops
class ErrorInfo
{
public Exception Error { get; set; }
public int Outer { get; set; }
public int Inner { get; set; }
}
class Program
{
static void Main(string[] args)
{
// something to store execeptions from inner thread loop
var errors = new ConcurrentBag<ErrorInfo>();
// no need to wrap a try around this simple loop
// unless you want an exception to stop the loop
for (int outer = 0; outer < 10; outer++)
{
var tasks = new Task[50];
for (int inner = 0; inner < 50; inner++)
{
var outerLocal = outer;
var innerLocal = inner;
tasks[inner] = Task.Factory.StartNew(() =>
{
try
{
Thread.Sleep(innerLocal);
if (innerLocal % 5 == 0)
{
throw new Exception("Test of " + innerLocal);
}
}
catch (Exception e)
{
errors.Add(new ErrorInfo
{
Error = e,
Inner = innerLocal,
Outer = outerLocal
});
}
});
}
Task.WaitAll(tasks);
}
Console.WriteLine("Error bag contains {0} errors.", errors.Count);
Console.ReadLine();
}
}
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Looking for some sample code (C#) for a simple thread pool implementation.
I found one on codeproject, but the codebase was just huge and I don't need all that functionality.
This is more for educational purposes anyways.
This is the simplest, naive, thread-pool implementation for educational purposes I could come up with (C# / .NET 3.5). It is not using the .NET's thread pool implementation in any way.
using System;
using System.Collections.Generic;
using System.Threading;
namespace SimpleThreadPool
{
public sealed class Pool : IDisposable
{
public Pool(int size)
{
this._workers = new LinkedList<Thread>();
for (var i = 0; i < size; ++i)
{
var worker = new Thread(this.Worker) { Name = string.Concat("Worker ", i) };
worker.Start();
this._workers.AddLast(worker);
}
}
public void Dispose()
{
var waitForThreads = false;
lock (this._tasks)
{
if (!this._disposed)
{
GC.SuppressFinalize(this);
this._disallowAdd = true; // wait for all tasks to finish processing while not allowing any more new tasks
while (this._tasks.Count > 0)
{
Monitor.Wait(this._tasks);
}
this._disposed = true;
Monitor.PulseAll(this._tasks); // wake all workers (none of them will be active at this point; disposed flag will cause then to finish so that we can join them)
waitForThreads = true;
}
}
if (waitForThreads)
{
foreach (var worker in this._workers)
{
worker.Join();
}
}
}
public void QueueTask(Action task)
{
lock (this._tasks)
{
if (this._disallowAdd) { throw new InvalidOperationException("This Pool instance is in the process of being disposed, can't add anymore"); }
if (this._disposed) { throw new ObjectDisposedException("This Pool instance has already been disposed"); }
this._tasks.AddLast(task);
Monitor.PulseAll(this._tasks); // pulse because tasks count changed
}
}
private void Worker()
{
Action task = null;
while (true) // loop until threadpool is disposed
{
lock (this._tasks) // finding a task needs to be atomic
{
while (true) // wait for our turn in _workers queue and an available task
{
if (this._disposed)
{
return;
}
if (null != this._workers.First && object.ReferenceEquals(Thread.CurrentThread, this._workers.First.Value) && this._tasks.Count > 0) // we can only claim a task if its our turn (this worker thread is the first entry in _worker queue) and there is a task available
{
task = this._tasks.First.Value;
this._tasks.RemoveFirst();
this._workers.RemoveFirst();
Monitor.PulseAll(this._tasks); // pulse because current (First) worker changed (so that next available sleeping worker will pick up its task)
break; // we found a task to process, break out from the above 'while (true)' loop
}
Monitor.Wait(this._tasks); // go to sleep, either not our turn or no task to process
}
}
task(); // process the found task
lock(this._tasks)
{
this._workers.AddLast(Thread.CurrentThread);
}
task = null;
}
}
private readonly LinkedList<Thread> _workers; // queue of worker threads ready to process actions
private readonly LinkedList<Action> _tasks = new LinkedList<Action>(); // actions to be processed by worker threads
private bool _disallowAdd; // set to true when disposing queue but there are still tasks pending
private bool _disposed; // set to true when disposing queue and no more tasks are pending
}
public static class Program
{
static void Main()
{
using (var pool = new Pool(5))
{
var random = new Random();
Action<int> randomizer = (index =>
{
Console.WriteLine("{0}: Working on index {1}", Thread.CurrentThread.Name, index);
Thread.Sleep(random.Next(20, 400));
Console.WriteLine("{0}: Ending {1}", Thread.CurrentThread.Name, index);
});
for (var i = 0; i < 40; ++i)
{
var i1 = i;
pool.QueueTask(() => randomizer(i1));
}
}
}
}
}
There is no need to implement your own, since it is not very hard to use the existing .NET implementation.
From ThreadPool Documentation:
using System;
using System.Threading;
public class Fibonacci
{
public Fibonacci(int n, ManualResetEvent doneEvent)
{
_n = n;
_doneEvent = doneEvent;
}
// Wrapper method for use with thread pool.
public void ThreadPoolCallback(Object threadContext)
{
int threadIndex = (int)threadContext;
Console.WriteLine("thread {0} started...", threadIndex);
_fibOfN = Calculate(_n);
Console.WriteLine("thread {0} result calculated...", threadIndex);
_doneEvent.Set();
}
// Recursive method that calculates the Nth Fibonacci number.
public int Calculate(int n)
{
if (n <= 1)
{
return n;
}
return Calculate(n - 1) + Calculate(n - 2);
}
public int N { get { return _n; } }
private int _n;
public int FibOfN { get { return _fibOfN; } }
private int _fibOfN;
private ManualResetEvent _doneEvent;
}
public class ThreadPoolExample
{
static void Main()
{
const int FibonacciCalculations = 10;
// One event is used for each Fibonacci object
ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations];
Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations];
Random r = new Random();
// Configure and launch threads using ThreadPool:
Console.WriteLine("launching {0} tasks...", FibonacciCalculations);
for (int i = 0; i < FibonacciCalculations; i++)
{
doneEvents[i] = new ManualResetEvent(false);
Fibonacci f = new Fibonacci(r.Next(20,40), doneEvents[i]);
fibArray[i] = f;
ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);
}
// Wait for all threads in pool to calculation...
WaitHandle.WaitAll(doneEvents);
Console.WriteLine("All calculations are complete.");
// Display the results...
for (int i= 0; i<FibonacciCalculations; i++)
{
Fibonacci f = fibArray[i];
Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);
}
}
}