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();
Related
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.
This question already has answers here:
Waiting for all threads to complete, with a timeout
(10 answers)
Closed 6 years ago.
I want the for loop to complete before I print the result, in:
for (int i = 0; i < 5; i++)
{
(new System.Threading.Thread(() =>
{
if (TimeTakingMethod())
{
++nResult;
}
})).Start();
}
Console.WriteLine("Count = " + nResult);
but Console.WriteLine will not wait for those threads to finish because printing is done on the main thread.
If I change it to:
System.Threading.Thread t = new System.Threading.Thread(() =>
{
for (int i = 0; i < 5; i++)
{
(new System.Threading.Thread(() =>
{
if (TimeTakingMethod())
{
++nResult;
}
})).Start();
}
});
t.Start();
t.Join();
Console.WriteLine("Count = " + nResult);
it will still not solve the problem because the nested threads will not be waited for.
Any simple solution to this? Thanks for going through this.
You should store the created threads to control them, I used a List.
int nResult = 0;
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 5; i++)
{
Thread thread = new System.Threading.Thread(() =>
{
if (TimeTakingMethod())
{
++nResult;
}
});
thread.Start();
threads.Add(thread);
}
foreach (Thread thread in threads)
thread.Join();
Console.WriteLine("Count = " + nResult);
An example of how you could do this:
int result = 0;
Task.WaitAll(Enumerable.Range(0, 5)
.Select(index => Task.Factory.StartNew(() =>
{
// Do thread things...
Interlocked.Increment(ref result);
})).ToArray());
Console.WriteLine(result);
The two important things to note are Task.WaitAll which will cause the program to wait for all tasks to complete before moving on to the WriteLine call.
Also Interlocked.Increment will allow you to safely increment result from any thread.
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.
I have used threading in my web application which I have mentioned below:
var t1 = new Thread(F1);
t1.IsBackground = true;
t1.Start();
var t2 = new Thread(F2);
t2.IsBackground = true;
t2.Start();
var t3 = new Thread(F3);
t3.IsBackground = true;
t3.Start();
var t4 = new Thread(F4);
t4.IsBackground = true;
t4.Start();
t1.Join();
t2.Join();
t3.Join();
t4.Join();
This is working fine and giving me the desired output.
Do I need to kill/Dispose the thread after this, if yes then how ?
Please guide.
I have told that if I do not dispose it, it might raise performance issue.
The call to Join() is what de-allocates the thread. You don't have to do anything else. Just make sure that the threads clean up any resources they might be using before they exit.
That said, I would urge you to look into using the thread pool or the Task Parallel Library (TPL) rather than explicitly managing threads. They're easier to use, and handle this kind of thing much more smoothly.
If I were in your shoes, I'd be using a ThreadPool instead of manual threads. It handles all that stuff itself, and you don't have the overhead of creating and destroying threads. The code will probably be slightly more complex, because you'll need to use a ManualResetEvent instead of a simple Thread.Join() (see How can I accomplish ThreadPool.Join?), but you won't have to worry about creating too many threads, and it's nearly 40x faster.
Here's the class for a test I wrote comparing the two approaches:
class ThreadPoolVsThreads
{
private static readonly PerformanceMonitor threadPoolTest = new PerformanceMonitor("ThreadPoolTest");
private static readonly PerformanceMonitor threadTest = new PerformanceMonitor("ThreadTest");
private const int iterations = 100;
private const int threads = 10;
private static long somevalue;
public static void Test()
{
TestHelper.PerformTest(10, threadPoolTest, ThreadPoolTest);
TestHelper.PerformTest(10, threadTest, ThreadTest);
}
private static void ThreadPoolTest(int iteration)
{
for (int i = 0; i < iterations; i++)
{
var resetEvents = new ManualResetEvent[threads];
for (int j = 0; j < threads; j++)
{
var re = new ManualResetEvent(false);
resetEvents[j] = re;
ThreadPool.QueueUserWorkItem(o =>
{
somevalue++;
re.Set();
});
}
WaitHandle.WaitAll(resetEvents);
}
}
private static void ThreadTest(int iteration)
{
for (int i = 0; i < iterations; i++)
{
var threadArray = new Thread[threads];
for (int j = 0; j < threads; j++)
{
var thread = new Thread(o => somevalue++);
threadArray[j] = thread;
thread.Start();
}
for (int j = 0; j < threads; j++)
{
threadArray[j].Join();
}
}
}
}
And here's the output for five runs:
ThreadPoolTest action completed: iteration = 1, completionTime = 53, averageCompletionTime = 53.000
ThreadTest action completed: iteration = 1, completionTime = 2128, averageCompletionTime = 2128.000
ThreadPoolTest action completed: iteration = 2, completionTime = 42, averageCompletionTime = 47.500
ThreadTest action completed: iteration = 2, completionTime = 2149, averageCompletionTime = 2138.500
ThreadPoolTest action completed: iteration = 3, completionTime = 65, averageCompletionTime = 53.333
ThreadTest action completed: iteration = 3, completionTime = 2078, averageCompletionTime = 2118.333
ThreadPoolTest action completed: iteration = 4, completionTime = 72, averageCompletionTime = 58.000
ThreadTest action completed: iteration = 4, completionTime = 2137, averageCompletionTime = 2123.000
ThreadPoolTest action completed: iteration = 5, completionTime = 43, averageCompletionTime = 55.000
ThreadTest action completed: iteration = 5, completionTime = 2085, averageCompletionTime = 2115.400
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