views:

56

answers:

2

This is a two part question.

First, let's say that I have a function that is executing in a another thread:

private AutoResetEvent StopEvent = new AutoResetEvent( false);

public void WorkerThread()
{
  while( !StopEvent.WaitOne( 10)) {
    a();
    b();
    c();
  }
}

Now I want to pause this thread. Thread.Suspend is out of the question because it can't guarantee me a deadlock-free system after calling it. Waiting on another AutoResetEvent is also not desired because of pause "granularity" would be too large. I have come up with two "solutions", but am not thrilled about either of them (but #2 is preferred at the moment):

1) interleave PauseEvent.WaitOne() everywhere:

private AutoResetEvent StopEvent = new AutoResetEvent( false);
private ManualResetEvent PauseEvent = new ManualResetEvent( true);

public void WorkerThread()
{
  while( !StopEvent.WaitOne( 10)) {
    PauseEvent.WaitOne( 0);
    a();
    PauseEvent.WaitOne( 0);
    b();
    PauseEvent.WaitOne( 0);
    c();
  }
}

2) force a(), b(), and c() to throw a MyException. Then I can wait in the catch block until a "resume" button click signals PauseEvent:

private AutoResetEvent StopEvent = new AutoResetEvent( false);
private AutoResetEvent PauseEvent = new AutoResetEvent( false);

public void WorkerThread()
{
  while( !StopEvent.WaitOne( 10)) {
    try {
      a();
      b();
      c();
    } catch( MyException) {
      PauseEvent.WaitOne(); // wait indefinitely until signaled by another thread
    }
  }
}

(2) really seems like the only way to do this, but I'd like to know if anyone has tried another method of "pausing".

Secondly, the part that I'm getting tripped up on is a nice way for solution #2 to induce the exception in the first place. At the moment, I've basically instrumented the low-level code called by a(), b(), and c() to look for an event to be signaled that tells them to throw MyException. This is the only way I know of that you can induce behavior on one thread from another.

What I'd really like to know is (and I'm pretty sure it's not possible), is there some crazy way in .NET to make a worker thread register an event handler, so that when I fire the event from my GUI, that the worker thread immediately stops what it's doing and execute the handler? I guess I'm basically looking for something like an interrupt service routine like what you'd typically implement on a microcontroller.

A: 

I'm not aware of a microcontroller-style approach with priority interrupts in .Net. But in the meantime you might want to consider a shared flag that your thread continually checks to see if it should pause or run. Once it detects a request to pause then it can wait using Thread.Sleep or a Timer to check for permission to run. Perhaps not as elegant as what you were hoping for but it is predictable and easy to implement.

ebpower
The flag approach is basically my #1 implementation above. Sure is a shame that this might be the only way to do it. I was working on implementation #2 today, but that has its own share of quirky behavior in the system.
Dave
A: 

After working on a few different approaches to this problem, I think I have something that works well enough. I basically went with #2, because it leverages the fundamental behavior of an AutoResetEvent for pausing and resuming.

My threads run state machines that are derived from Stateless, so I was able to put all of the pause and resume functionality in the base class, which makes my code nice and clean. I can also have client-specific functionality by overriding methods in the derived class.

In the end, there were tradeoffs between granularity of pausing and elegance of code. I sacrificed the granularity so I didn't have to pepper WaitOne()s everywhere.

Dave