tags:

views:

45

answers:

2

Hi,

I have some utility class with worker thread with simple exit condition. I use this class in my application. Worker thread is created and started in class constructor.

class MyClass
{
  Thread _thread;

// unrelevant details are omitted
void WorkerThreadRoutine
{
  while(_running)
 {
   // do some useful background work here
 }
}
}

My question is WHEN do I have to set _running=false. In C++ with deterministic resource deallocation life is easy - I use object destructors and don't care.

I would write something like

~MyClass()
{
  _running = false;
}

In C# there no destructors in C++ sense. Do I have to write some Dispose() function here and use IDisposable? I can of course provide a Stop() function. But when do I have to call it? Is there a way to automatically have my Stop function called?

What is right pattern here? I have lots of MyClass intances across my application.

Right now my application hangs on exit.

+2  A: 

The reason your application hangs is that new threads are created as foreground threads per default. The CLR will keep your process alive as long as you have any running foreground threads.

To get rid of the thread, just exit the code it is running. This will make the thread available for cleanup and once it has shut down the process will be able to close as well (assuming you have no other foreground threads running).

Brian Rasmussen
+1  A: 

In C++, you'd normally explicitly call the delete operator. That's not different from explicitly calling a Stop() method in C#.

The C++ compiler can auto-generate the delete operator call if your object is a local variable of a method. That maps well to IDisposible in C# with the using statement:

void SomethingSlow() {
  using (var obj = new MyClass()) {
    // etc..
  }
}

class MyClass : IDisposable {
  private ManualResetEvent mStop = new ManualResetEvent(false);
  public Dispose() {
    mStop.Set();
  }
  // etc...
}

Your thread probably doesn't stop right now because you forgot to declare the _running field as volatile. Using an event can help avoid problems like that. You can set the thread's IsBackground property to true to prevent the thread from hanging your program termination. That's a band-aid, not a fix.

Hans Passant