views:

24

answers:

1

I want to create a background thread that's owned by an object. When that object is no longer needed, so is its background thread.

pseudo code of what I currently have:

ResetEvent _isCanceled
ResetEvent _hasWork
ThreadSafeQueue _workItems

Init()
  new BackgroundThread(ThreadLoop).Start()

AddWork(work)
  _workItems.Enqueue(work)
  _hasWork.Set()

Dispose()
  _isCanceled.Set()

ThreadLoop()
  while(!_isCanceled)
    if(_hasWork)
      Execute(_workItems.Dequeue())
    if(_workItems.IsEmpty)
      _hasWork.Reset()
    WaitHandle.WaitAny(_isCanceled, _hasWork)

The problem is that if someone (not me of course) forgets to call Dispose(), the thread will never be stopped. What I understood about Finalize is that you can't refer to any members, because you must assume they are null-ed already.

So how can I stop the background thread if the owning object is or gets gc-ed?

+1  A: 

Finalize is right place to do this. Just check is not it null.

Andrey
So then what do you do if _isCanceled is null? Just let the background thread live? That smells like a memory leak to me...
Patrick Huizinga
if it is null then it was collected and tread should finish existence. other way is to have WeakReference to creator of thread and check it occasionally.
Andrey
I guess using WeakReference is the way to go then. Though that does mean I need to let the thread wake up once in a while. Although I guess that will be better than to risk letting the thread live forever.
Patrick Huizinga
just add to your while condition checking of WeakReference to creator
Andrey