Reputation: 1
I am trying to reuse two threads in a while loop like this:
while (condition)
{
thread1.Start();
thread1.Join();
thread2.Start();
}
I am using thread1.Join()
because I want thread2 to wait for the first's thread's finalization.
However, after thread1 runs one time I get the error: 'Thread is running or terminated; it cannot restart.'
From what I read, a thread can only be started once so that would imply that threads in loops are just impossible to work but I would guess that there is a way somehow.
One thing that I forgot to mention is that each thread requires input from the keyboard so it should work like this: thread1 runs -> input from the keyboard -> thread 2 runs -> input from the keyboard.
Last Update: I made it work using this:
int i= 0;
while(condition)
{
thread1[i] = new Thread(() => player1Turn(ref creditP1, ref positionP1, ref creditP2, propertyPrices, playerProperty));
thread1[i].Start();
thread1[i].Join();
thread2[i] = new Thread(() => player2Turn(ref creditP2, ref positionP2, ref creditP1, propertyPrices, playerProperty));
thread2[i].Start();
thread2[i].Join();
i++;
}
I know this is a horrible implementation because I use a bunch of threads but for now it will do. I will surely look into Thread pooling as many of you said. Thanks for your time!
Upvotes: 0
Views: 467
Reputation: 117104
You could consider using Microsoft's Reactive Framework (NuGet "System.Reactive") to get access to the EventLoopScheduler
class. Each instance of this class creates a single thread that you can schedule code to run on - either immediately or by a scheduled time.
In your case you can hand code off from one instance of the EventLoopScheduler
to another. It might be a little more convoluted than a simple while
loop, but it should let you do what you want.
I've created an example to show what can be done. I'm implemented the below function, processing even numbers of one EventLoopScheduler
and odd numbers on another. When I get a value of 1
I stop.
Here's the code:
var els1 = new EventLoopScheduler();
var els2 = new EventLoopScheduler();
int value = 15;
void Execute()
{
if (value != 1)
{
if (value % 2 == 0)
{
els2.Schedule(() =>
{
Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}: {value}");
value = value / 2;
els1.Schedule(Execute);
});
}
else
{
Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}: {value}");
value = value * 3 + 1;
els1.Schedule(Execute);
}
}
else
Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}: {value}");
}
els1.Schedule(Execute);
When the value is even I can els2.Schedule(() =>
and at the end of that call I pass back to els1.Schedule(() =>
to complete the call. This just continues to recursively call itself until the function computes a 1
.
Here's a typical run:
22: 15
37: 46
22: 23
37: 70
22: 35
37: 106
22: 53
37: 160
37: 80
37: 40
37: 20
37: 10
22: 5
37: 16
37: 8
37: 4
37: 2
22: 1
Note the hand-off two the two threads. Evens run on thread 37
and odds on thread 22
.
You should call .Dispose()
on each EventLoopScheduler
to allow the threads to terminate.
Upvotes: 1