Is it possible to know which thread completed first? - c#

If I have fire 3 threads. Is it possible to know which thread completed first.
Some sample code
Thread thread1 = new Thread(() => MyFunc());
Thread thread2 = new Thread(() => MyFunc());
Thread thread3 = new Thread(() => MyFunc());
thread1.Start();
thread2.Start();
thread3.Start();
while (thread1.IsAlive || thread2.IsAlive || thread3.IsAlive)
{
//I need condition to which thread dead first.
}

You can use Interlocked.CompareExchange to set the winning thread:
static Thread winner = null;
private static void MyFunc()
{
Thread.Sleep((int)(new Random().NextDouble() * 1000));
Interlocked.CompareExchange(ref winner, Thread.CurrentThread, null);
}
public static void Main()
{
Thread thread1 = new Thread(() => MyFunc());
Thread thread2 = new Thread(() => MyFunc());
Thread thread3 = new Thread(() => MyFunc());
thread1.Name = "thread1";
thread2.Name = "thread2";
thread3.Name = "thread3";
thread1.Start();
thread2.Start();
thread3.Start();
thread1.Join();
thread2.Join();
thread3.Join();
Console.WriteLine("The winner is {0}", winner.Name);
}
Live Demo
UPDATE: If you don't want all threads to finish before you check, there is an easier method using AutoResetEvents and WaitHandle.WaitAny():
private static void MyFunc(AutoResetEvent ev)
{
Thread.Sleep((int)(new Random().NextDouble() * 1000));
ev.Set();
}
public static void Main()
{
AutoResetEvent[] evs = {new AutoResetEvent(false), new AutoResetEvent(false), new AutoResetEvent(false)};
Thread thread1 = new Thread(() => MyFunc(evs[0]));
Thread thread2 = new Thread(() => MyFunc(evs[1]));
Thread thread3 = new Thread(() => MyFunc(evs[2]));
thread1.Start();
thread2.Start();
thread3.Start();
int winner = WaitHandle.WaitAny(evs);
Console.WriteLine("The winner is thread{0}", winner + 1);
}
Live Demo

one simple workaround would be that you write the thread name to a list or something when it completes?

All threads can have an arbitrary delay after the last instruction of your code is completed. After the last instruction has run the OS still has some work to do. It can take an arbitrarily long time.
For that reason it is never meaningful to find out what thread completed first. This is the XY-Problem. This question is meaningless. Its answer will not help you accomplish anything. Ask a new question with the real problem.
You probably want to tell which one of multiple side-effects happened first. Even if they completed in order A, B the threads they ran on can complete in any order. The thread order tells you nothing.

Related

Start multiple threads at the same time without slowing down

I know that this question is everywhere but I couldn't find what suits me.
I am trying to start 10 threads running at the same time without slowing down each thread.
My problem is that when I start the threads manually, they are very fast. But if I start them using a loop, they are very slow.
Here is where it is fast:
Thread tid1 = new Thread(new ThreadStart(Thread));
tid1.Start();
Thread tid2 = new Thread(new ThreadStart(Thread));
tid2.Start();
Thread tid3 = new Thread(new ThreadStart(Thread));
tid3.Start();
Thread tid4 = new Thread(new ThreadStart(Thread));
tid4.Start();
Thread tid5 = new Thread(new ThreadStart(Thread));
tid5.Start();
Thread tid6 = new Thread(new ThreadStart(Thread));
tid6.Start();
Thread tid7 = new Thread(new ThreadStart(Thread));
tid7.Start();
Thread tid8 = new Thread(new ThreadStart(Thread));
tid8.Start();
Thread tid9 = new Thread(new ThreadStart(Thread));
tid9.Start();
Thread tid10 = new Thread(new ThreadStart(Thread));
tid10.Start();
Slow methods which I've tried:
1:
foreach (var i in Enumerable.Range(1, 10))
{
Thread tid = new Thread(new ThreadStart(Thread));
tid.Start();
}
2:
Parallel.ForEach(Enumerable.Range(1, 10), i =>
{
Thread tid = new Thread(new ThreadStart(Thread));
tid.Start();
});
Any help would be appreciated.
Thanks!
After a bit of tinkering, this method seems quite quick:
List<Thread> threadlist = new List<Thread>();
for (int i = 0; i <= 10; i++)
threadlist.Add(new Thread(new ThreadStart(wastetime)));
foreach (Thread t in threadlist)
t.Start();
Make a list of the threads, then start them once the list is assembled. Bonus points if the thread creation sub is on it's own mini thread to.
Though beware of magic, each thread has overhead and extra processing involved, so if the tasks being performed on each thread are short-lived, the whole threading idea will be losing performance rather than gaining it.

mimic concurrent threads (on the same resource/method)

Is there any way that I mimic in an short simple illustrative example of concurrent threads, that 2 threads can start the same method at the same time, and the processing is mixed between the two?
In the below example, I want to see sth like:
1 thread1
1 thread2
2 thread1
2 thread2
..
10 thread1
10 thread2
Instead, I get something like:
1 thread1
2 thread1
...
10 thread1
1 thread2
2 thread2
...
10 thread2
Be kind, I'm just starting to learn threads.
In short, I want to simulate the effect of the two threads starting at exactly the same time, not one immediately after the other.
After I achieve the above mentioned, I want to use the lock in order for thread1 to completely finish executing before starting thread2. This already happens in my example even before employing lock.
using System;
using System.Threading;
public class Program
{
public class C1
{
private object obj = new object();
public void Ten()
{
//lock(obj)
//{
for(int i=1; i<=10; i++)
{
Console.WriteLine(i + " " + Thread.CurrentThread.Name);
}
//}
}
}
public static void Main()
{
Thread t1 = new Thread(new ThreadStart(new C1().Ten));
Thread t2 = new Thread(new ThreadStart(new C1().Ten));
t1.Name = "thread1";
t2.Name = "thread2";
t1.Start();
t2.Start();
}
}
as ESG mentioned in the comment, the code runs too fast. That's why you are not getting expected output. Try adding some sleep inside the loop to get the expected result.
using System;
using System.Threading;
public class Program
{
public class C1
{
private static object obj = new object();
public void Ten()
{
//lock(obj)
//{
for(int i=1; i<=10; i++)
{
Console.WriteLine(i + " " + Thread.CurrentThread.Name);
Thread.Sleep(1000); //<-- add sleep
}
//}
}
}
public static void Main()
{
Thread t1 = new Thread(new ThreadStart(new C1().Ten));
Thread t2 = new Thread(new ThreadStart(new C1().Ten));
t1.Name = "thread1";
t2.Name = "thread2";
t1.Start();
t2.Start();
}
}
On the second note about locking the resource so that thread2 should wait for thread1 to complete. You will need to mark the obj as static variable.
Hope it helps.

Combine Threading.Timer with new Thread()?

I have a console application that runs at :00 of every hour. This console application copies files at :15 and :30 of the very same hour.
This was my initial code, where I use a WHILE loop to check the current minute. I would like to replace the WHILE loop with a System.Threading.Timer.
Using Threading.Timer and without using a loop, how can I launch Thread0 at 15 minutes after the start of the console app and Thread1 at 30 minutes? I do not want to use 3rd-party, open-source solutions.
CancellationTokenSource cts0 = new CancellationTokenSource();
CancellationTokenSource cts1 = new CancellationTokenSource();
Thread Thread0, Thread1;
DateTime TaskRunDateTime = DateTime.Now;
DateTime RightNow = DateTime.Now;
while (!thread0Running || !thread1Running)
{
if (RightNow.Minute == 15)
{
thread0Running = true;
Class myClass0 = new Class();
Thread0 = new Thread(() => myClass0.CopyFiles(15, cts0.Token));
Thread0.Start();
}
else if (RightNow.Minute == 30)
{
thread1Running = true;
Class myClass1 = new Class();
Thread1 = new Thread(() => myClass1.CopyFiles(30, cts1.Token));
Thread1.Start();
}
RightNow = DateTime.Now;
}
for (; ; )
{
fileCount = Directory.GetFiles(destPath, FileDate + "*.xml").Length;
If (fileCount == 20)
{
// All 20 files have been copied because the two threads have finished
RunExternalReportGeneratorEXE();
break;
}
else if (RightNow >= TaskRunDateTime.AddHours(2))
{
// Task took over 2 hours to complete.
// Cancel Thread0, Thread1 and run 3rd-party executable.
cts0.Cancel();
cts1.Cancel();
RunExternalReportGeneratorEXE();
break;
}
At the point you application starts you can calculate how long until X:15 and X:30 will fall. You could then use the Timer's constructor to schedule the start time of the timer callback and the frequency.
Create two ManualResetEvent objects that you can wait on. Then create two timers:
ManualResetEvent Copy1Done = new ManualResetEvent(false);
ManualResetEvent Copy2Done = new ManualResetEvent(false);
Timer t1 = new Timer((s) =>
{
Class myClass0 = new Class();
myClass0.CopyFiles(15, cts0.Token);
Copy1Done.Set();
}, null, TimeSpan.FromMinutes(15), TimeSpan.FromMilliseconds(-1));
Timer t1 = new Timer((s) =>
{
Class myClass1 = new Class();
myClass0.CopyFiles(30, cts1.Token);
Copy2Done.Set();
}, null, TimeSpan.FromMinutes(30), TimeSpan.FromMilliseconds(-1));
Those are one-shot timers; they'll fire once, and then won't fire again.
Now, you want to wait up to two hours for the copies to complete. That's where the ManualResetEvent objects come in. Create an array of the events:
WaitHandle[] handles = new WaitHandle[] {Copy1Done, Copy2Done};
// wait for both events to be signaled, or for two hours
if (!WaitHandle.WaitAll(handles, TimeSpan.FromHours(2)))
{
// took too long. Cancel the copies.
cts0.Cancel();
cts1.Cancel();
// you might want to wait here for the threads to exit.
// otherwise you might have a problem with a locked file.
}
// and run the program
RunExternalReportGeneratorEXE();
I don't want to write the whole code here for you but to give you an idea what you can do with thread timer:
void CreateTimer()
{
// Create an event to signal the timeout count threshold in the
// timer callback.
AutoResetEvent autoEvent = new AutoResetEvent(false);
// Create an inferred delegate that invokes methods for the timer.
TimerCallback tcb = CheckStatus;
// Create a timer that signals the delegate to invoke
// CheckStatus after 15 minutes.
// thereafter.
Console.WriteLine("{0} Creating timer.\n", DateTime.Now.ToString("h:mm:ss.fff"));
System.Threading.Timer Timer stateTimer = new Timer(tcb, autoEvent, 1000 * 60 *15, 0);
//Wait for 15 minutes
autoEvent.WaitOne(1000 * 60 *15, false);
stateTimer = new Timer(tcb, null, 1000 * 60 *30, 0);
}
// This method is called by the timer delegate.
public void CheckStatus(Object stateInfo)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), stateInfo);
}
public void DoWork(Object stateInfo)
{
AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
autoEvent.Set();
//Change your worktype here.
CancellationTokenSource cts0 = new CancellationTokenSource();
Class myClass1 = new Class();
myClass1.CopyFiles(30, cts0.Token);
}

WaitOne() waits forever even though all events fired

Threaded is suppossed to create 4 seperate threads and wait for each of them till they finish. Each thread sleeps for a while and terminates only when the shared Mutex opbject is not occupied by another thread and then signal trough a event that it finished(This is a simplified version of my code but fails at the same spot)
But what happens is that most of the time the Main thread will wait forever at one of the WaitOne() seemingly at random.
Also I had to comment-out some parts of my code out because it led to even more unexpected behaviour (I.e somehow after each thread finished the main thread would jump back into the for clause and cause a IndexOutOfBounds)
class Threading
{
static Mutex CM;
static List<Manga> SharedList;
static ManualResetEvent CEvent = new ManualResetEvent(false);
static ManualResetEvent Event1 = new ManualResetEvent(false);
static ManualResetEvent Event2 = new ManualResetEvent(false);
static ManualResetEvent Event3 = new ManualResetEvent(false);
static ManualResetEvent Event4 = new ManualResetEvent(false);
public List<Manga> ThreadedMangaIndexCrawl(int MaxThreads)
{
CM = new Mutex(false);
SharedList = new List<Manga>();
ManualResetEvent[] evs = new ManualResetEvent[4];
evs[0] = Event1; // Event for t1
evs[1] = Event2; // Event for t2
evs[2] = Event3; // Event for t3
evs[3] = Event4; // Event for t4
/*for (int i = 0; i < MaxThreads + 1; i++)
{
if (i > MaxThreads)
{ break; }
Thread t = new Thread(() => this.StartIndexCrawling(1,i,i+1,evs[i]));
t.Start();
}*/
int i = 0;
Thread t1 = new Thread(() => this.StartIndexCrawling(1, i, i + 1, evs[i]));
t1.Name = "Thread" + i;
t1.Start();
i++;
Thread t2 = new Thread(() => this.StartIndexCrawling(1, i, i + 1, evs[i]));
t2.Name = "Thread" + i;
t2.Start();
i++;
Thread t3 = new Thread(() => this.StartIndexCrawling(1, i, i + 1, evs[i]));
t3.Name = "Thread" + i;
t3.Start();
i++;
Thread t4 = new Thread(() => this.StartIndexCrawling(1, i, i + 1, evs[i]));
t4.Name = "Thread" + i;
t4.Start();
/* foreach (var e in evs)
{
e.WaitOne();
}*/
evs[0].WaitOne();
evs[1].WaitOne();
evs[2].WaitOne();
evs[3].WaitOne();
return SharedList;
}
void StartIndexCrawling(int Target, int Start, int End, ManualResetEvent E)
{
Thread.Sleep(1000);
CM.WaitOne();
CM.ReleaseMutex();
E.Set();
}
}
Any help would be great
Most likely, all four threads will execute:
this.StartIndexCrawling(1, 3, 3 + 1, evs[4]);
This has to do with your use of closures. All four threads will be bound to the variable i and use whatever value it has once the code is executed (and not the value when the Thread object is created).
Your code is unlikely to work if all four threads use the same value.
See Codo's answer.
Here is what you should do to solve it:
int i = 0;
Thread t1 = new Thread(() => this.StartIndexCrawling(1, 0, 1, Event1));
t1.Name = "Thread" + i;
t1.Start();
i++;
Thread t2 = new Thread(() => this.StartIndexCrawling(1, 1, 2, Event2));
t2.Name = "Thread" + i;
t2.Start();
i++;
Thread t3 = new Thread(() => this.StartIndexCrawling(1, 2, 3, Event3));
t3.Name = "Thread" + i;
t3.Start();
i++;
Thread t4 = new Thread(() => this.StartIndexCrawling(1, 3, 4, Event4));
t4.Name = "Thread" + i;
t4.Start();

How to use wait handles in C# threading?

I have three threads in my program and I want that when thread one finishes it signals thread 2 to start and when thread 2 finishes it should signal thread 3 to start.
How can I achieve this, I know there are wait handles to do that in C#, but I don't know how to use them ?
Following is the code of my program:
class Program
{
static void Main(string[] args)
{
Thread t1 = new Thread(Task1);
Thread t2 = new Thread(Task2);
Thread t3 = new Thread(Task3);
t1.Start();
t2.Start();
t3.Start();
Console.Read();
}
public static void Task1()
{
Console.WriteLine("I am assigned task 1:");
for (int i = 0; i < 50; i++)
{
Console.WriteLine("Task1" );
}
}
public static void Task2()
{
Console.WriteLine("I am assigned task 2:");
for (int i = 0; i < 50; i++)
{
Console.WriteLine("Task2");
}
}
public static void Task3()
{
Console.WriteLine("I am assigned task 3:");
for (int i = 0; i < 50; i++)
{
Console.WriteLine("Task3");
}
}
}
You need to pass events into the threaded functions that indicate what to signal when each one has finished and what to wait on before they run. Take a look at the (untested) code below to see what I mean:
class Program
{
static void Main(string[] args)
{
Thread t1 = new Thread(Task1);
ManualResetEvent e1=new ManualResetEvent(false);
Thread t2 = new Thread(Task2);
ManualResetEvent e2=new ManualResetEvent(false);
Thread t3 = new Thread(Task3);
ManualResetEvent e3=new ManualResetEvent(false);
t1.Start(()=>Task1(e1));
t2.Start(()=>Task2(e1,e2));
t3.Start(()=>Task3(e2,e3);
Console.Read();
t1.Join();
t2.Join();
t3.Join();
}
public static void Task1(EventWaitHandle handle)
{
Console.WriteLine("I am assigned task 1:");
for (int i = 0; i < 50; i++)
{
Console.WriteLine("Task1" );
}
handle.Set();
}
public static void Task2(EventWaitHandle waitFor, EventWaitHandle handle)
{
waitFor.WaitOne();
Console.WriteLine("I am assigned task 2:");
for (int i = 0; i < 50; i++)
{
Console.WriteLine("Task2");
}
handle.Set();
}
public static void Task3(EventWaitHandle waitFor, EventWaitHandle handle)
{
waitFor.WaitOne();
Console.WriteLine("I am assigned task 3:");
for (int i = 0; i < 50; i++)
{
Console.WriteLine("Task3");
}
handle.Set();
}
}
It appears that you want to run Tasks 1 - 3 to execute synchronously. So, you might as well do:
Task1();
Task2();
Task3();
If you want to offload the execution of these tasks to another thread, you can do:
static void RunTasks()
{
Task1();
Task2();
Task3();
}
static void Main()
{
new Thread(RunTasks).Start();
}
If you really wanted each task to run on a separate thread, and wait for the previous task to finish, you can use the Thread.Join method.
EDIT:
Since you really want to use wait-handles to accomplish this, take a look at the ManualResetEvent class.
Notifies one or more waiting threads
that an event has occurred.
Call the WaitOne method on it to wait on the event, and the Set method to signal it.
Example (horribly contrived code):
var afterT1Event = new ManualResetEvent(false);
var afterT2Event = new ManualResetEvent(false);
Thread t1 = new Thread(() => { Task1(); afterT1Event.Set(); });
Thread t2 = new Thread(() => { afterT1Event.WaitOne(); Task2(); afterT2Event.Set(); });
Thread t3 = new Thread(() => { afterT2Event.WaitOne(); Task3(); });
t1.Start();
t2.Start();
t3.Start();
If you want to use WaitHandles to acheive these then you could do the following:
declare the following two fields:
static ManualResetEvent handle1 = new ManualResetEvent(false);
static ManualResetEvent handle2 = new ManualResetEvent(false);
then at the end of Task1, add this:
handle1.Set();
at the beginning of Task2, add:
handle1.WaitOne();
then at the end, add
handle2.Set();
then finally at the beginning of Task3 add
handle2.WaitOne();
This feels very artificial, almost like homework...
... but basically you can use Join on a thread to wait for it.
Or the old msdn tutorial/example is very reasonable on this: http://msdn.microsoft.com/en-us/library/aa645740(VS.71).aspx
You could use ManualResetEvents and WaitHandle.WaitAny. Basically when one thread is done you would notify the other thread by using a ManualResetEvent (ManualResetEvent.Set()).
ManualResetEvent threadFinished = new ManualResetEvent(false);
//You would set this in the thread that has finished
threadFinished.Set()
//You would use this in the thread that you want to wait for this event to be signalled
int nWait = WaitHandle.WaitAny(new ManualResetEvent[] { threadFinished }, 10, true);
//if yes stop thread
if (nWait == 0)
{
//Thread is finished
}
i think using thread.join() will be more simpler any other solution

Categories

Resources