Thread Strange Behaviour

C

Curious

Hi,

I have a worker thread running, where basically its operation is to
execute in an infinite loop.

Now, when I am suspending this thread, the CPU usage time is still
remaining 100%.

What could my problem be.


Thread t1 = new Thread(new ThreadStart(myMethod));
Console.Writeline("Press any key to start");
Console.Readline();
running = true;
t1.Start();
Console.Writeline("Press any key to suspend");
Console.Readline();
t1.Suspend();
Console.Readline();
... here CPU usage still 100%

myMethod()
{
while (running == true)
{
Code:
}
}


Can someone help me out
Thanks in Advance
 
N

Nicholas Paldino [.NET/C# MVP]

Curious,

You shouldn't use the Suspend method on a thread to synchronize work.
You should be using events or mutexes or some other synchronization
primitive to do this.

What is the purpose of calling Suspend?
 
C

Curious

I am using the Suspend to pause the execution.

To solve previous problem, I did as follows (Is this the correct way):

object objLock = new object();

myMethod()
{
while (running == true)
{
lock(objLock)
{
Code:
}
}
}


Thread t1 = new Thread(new ThreadStart(myMethod));
Console.Writeline("Press any key to start");
Console.Readline();
running = true;
t1.Start();

Console.Writeline("Press any key to suspend");
Console.Readline();
lock(objLock)
{
t1.Suspend();
}
Console.Readline();

Console.Writeline("Press any key to resume");
Console.Readline();
t1.Resume();
 
N

Nicholas Paldino [.NET/C# MVP]

Curious,

No, you aren't doing anything really and causing a really messy
situation.

If anything, create an event, and wait on that event handle. This will
cause execution to pause, depending on where you put it.
 
C

Curious

I read the part recommended. So whats the real use of suspend,
resume,etc methods?

Also, how can I get around the problem, to have the behaviour of
starting, stopping, pausing and resuming from a thread.
 
C

Curious

Is the following code safe??

protected void Execute()
{
while (Running == true)
{
Code:
if (Paused == true)
{
try
{
Thread.Sleep(Timeout.Infinite);
}
catch (ThreadInterruptedException){}
}
}
}

Thread t1 = new Thread(new ThreadStart(Execute));
Running = true;
Paused = false;
t1.Start();

Console.Writeline("Press any key to Pause");
Console.Readline();
Paused = true;

Console.Writline("Press any key to Resume");
Console.Readline();
Paused = true;
t1.Interrupt();

Console.Writline("Press any key to Stop");
Console.Readline();
Running = false;
 
J

Jon Skeet [C# MVP]

Curious said:
Is the following code safe??

<snip>

Well:

1) It depends on how Running and Paused are implemented (assuming
they're properties)
2) Even if it's thread-safe, it's not the way you're *meant* to pause
and resume threads. As I said before, you should use monitors or
waithandles - that's what they're *designed* for.

Jon
 
O

Ollie Riches

how about the following example console app - I am sure Jon will point out
some subtle problem with the example :)

using System;
using System.Threading;

namespace TestThread
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
private ManualResetEvent _pauseEvent = new ManualResetEvent(false);
private ManualResetEvent _stopEvent = new ManualResetEvent(false);
private ManualResetEvent _finishedEvent = new
ManualResetEvent(false);
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
Class1 c1 = new Class1();
// Pause the worker
c1._pauseEvent.Set();
Thread t1 = new Thread(new ThreadStart(c1.Worker));
t1.Start();
Console.WriteLine("Press ENTER to start worker");
Console.ReadLine();
// Start the worker
c1._pauseEvent.Reset();
Console.WriteLine("Press ENTER to pause worker");
Console.ReadLine();
// Pause worker
c1._pauseEvent.Set();
Console.WriteLine("Press ENTER to stop worker");
Console.ReadLine();
// Stop worker
c1._stopEvent.Set();
c1._pauseEvent.Reset();
c1._finishedEvent.WaitOne();
Console.WriteLine("Worker Stopped");
Console.WriteLine(Environment.NewLine);
Console.WriteLine("Press ENTER to exit");
Console.ReadLine();
}
private void Worker()
{
System.Diagnostics.Trace.WriteLine("Starting worker");
int i = 0;
// Check whether the worker is to shut down (waits for 100th of
second)
while(this._stopEvent.WaitOne(10, false) == false)
{
// Check whether the worker has been paused (waits for 100th
of second)
while(this._pauseEvent.WaitOne(10, false) == false)
{
i++;
System.Diagnostics.Trace.WriteLine("Iteration = " +
i + ", Date = " + DateTime.Now.ToString("U"));
}
}
System.Diagnostics.Trace.WriteLine("Shutting down worker");
this._finishedEvent.Set();
}
}
}

HTH

Ollie Riches
 
J

Jon Skeet [C# MVP]

Ollie said:
how about the following example console app - I am sure Jon will point out
some subtle problem with the example :)

Well, it's somewhat inefficient to wake up every 10ms (and personally I
don't like comparisons against boolean literals, but that's somewhat
different :) - I'd use WaitAny instead, and see what was signalled,
*or* use a single monitor and two flags (or even an enum) for
paused/terminated.

Having said that, I don't think it was unthreadsafe in any way :)

Jon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top