views:

59

answers:

3

Hi,

What I have is a loop reading some data and when a set of circumstances are met I need to instantiate a thread. However, the created thread might not complete before the loop criteria is met and I need to create another thread doing the same thing. This is part of an ocr app and I haven't done much thread work before.

while loop
  if(criteria)
  {
    observer = new BackgroundWorker();
    observer.DoWork += new DoWorkEventHandler(observer_DoObserving);
    observer.RunWorkerAsync();
  }

the observer_DoObserving function calls the ocr app, waits for a response and then processes it appropriately and sets observer = null at the end. So how would I create multiple instances of the 'observer' thread. Of course instantly I thought of a class structure, is this an appropriate way to do it or is there another way that is appropriate for threading.

I hope this makes sense.

Thanks, R.

+2  A: 

You could use the thread pool, specifically ThreadPool.

while (something)
{
    if (criteria)
    {
        // QueueUserWorkItem also has an overload that allows you to pass data
        // that data will then be passed into WorkerMethod when it is called
        ThreadPool.QueueUserWorkItem(new WaitCallback(WorkerMethod));
    }
}

// ...

private void WorkerMethod(object state)
{
    // do work here
}
LukeH
I'll check that out, thanks.
flavour404
How do you dispose of a thread in the threadpool when it's work is done? I just read quickly that 25 is the maximum, which is fine as the tasks are quick I am just worried that you quickly end up with 25 dead threads...
flavour404
@flavour404: You don't need to worry about disposing the thread. When your worker method returns the thread is automatically returned to the pool and re-used when/if necessary.
LukeH
And if you run out of the thread pool threads (e.g. all of them are in use concurrently) you should probably restructure your app to use fewer threads.
Judah Himango
A: 

I am not entirely able to grasp what you are doing exactly, so I may or may not be helpful here;

You seem to be, in part, asking if it's appropriate to create a class to hold some data indicating the state of a thread or what it's working on. That is entirely appropriate to do, provided the object is not an 'expensive' one to create. (no creating Exception objects and throwing them around all the time, for instance).

Andrew Barber
+1  A: 

How you handle this depends in large part on whether the background thread needs to communicate anything to the main thread when it's done. If the background thread really is "fire and forget", then there's no particular reason why you need to maintain a reference to the observer. So you could write:

while loop
{
  if(criteria)
  {
    BackgroundWorker observer = new BackgroundWorker();
    observer.DoWork += new DoWorkEventHandler(observer_DoObserving);
    observer.RunWorkerAsync();
  }
}

The thread does its work and goes away. observer is a local variable that goes out of scope when execution leaves the if block. There's no way that the variable will be overwritten if you have to start another observer thread before the first one is finished.

If you need to keep track of information for individual observers, then you'd create an object of some type (a class that you define) that contains information about the worker's state, and pass that to the RunWorkerAsync method. The worker can then modify that object and send you progress notifications (see the ProgressChanged event and the ReportProgress method), and also report the status when the worker has finished (see RunWorkerCompleted, the state object you passed to RunWorkerAsync will be in the RunWorkerCompletedEventArgs.UserState property).

Jim Mischel