tags:

views:

79

answers:

3

I put "volatile" because it's only vaguely so.

I have a class which has a property called "StopRequested". This flag can be set by other threads at any time, and needs to indicate to my code that it should stop what it's doing and exit (this is a Windows Service based process, and when Stop is called, all processing needs to clean up and stop).

I wish to create some other classes to do the actual brunt of the processing work, however these classes also have to be aware of the "stop" flag. You can't just pass the flag because it will pass a copy, and you can't pass properties as ref types.

So how do you propogate a property that might change at any time into other classes?

The only thing I can think of is to pass a reference to the parent class, but I dislike coupling the worker classes to the parent for one flag. Any suggestions would be appreciated.

EDIT:

Here's a basic example:

public class A
{
    public bool StopRequested { get; set; }

    private Worker = new Worker();

    public void DoWork();
    {
        worker.DoWork();
    }
}

public class Worker
{
    public void DoWork()
    {
        while(!StopRequested)
        {
            ....
        }
    }
}
A: 

Why don't to create an event to handle stop requests?

Rubens Farias
That's one option, and I had considered it, but in general the stop mechanism is a flag, not an event. An event would indicate that you can force a stop, while a flag is merely a "Stop when you get a chance" kind of deal. I just don't think the semantics call for an event.
Mystere Man
+1  A: 

You could have each of your worker classes have their own StopRequest property and then just set that whenever StopRequest is flagged.

private List<IStopable> WorkerClasses = new List< IStopable > ()


public Bool StopRequest{
    get
    {
          return _stopRequest;
    }
    set 
    {
        _stopReqest = value;

        foreach (var child in WorkerClasses)
            child.StopRequest = value;
    }
}
Courtney de Lautour
I like this. Nice and clean/
Mystere Man
+1  A: 

Like Rubens said, use an event. What you described basically defines event to a T:

Propagate a property change to other classes.

There is actually a facility in .NET that provides this already, albeit in a generic way: INotifyPropertyChanged. This interface provides a single event, PropertyChanged, that allows a class to notify any listeners of any property change.

In your case, you could easily provide your own interface that is more specific:

interface IStopNotifier
{
    event EventHandler StopRequested;
}

This interface would be implemented by your main work manager (whatever it is), and could propagate itself like so:

class WorkManager: IStopNotifier
{
    public event EventHandler StopRequested;

    protected void OnStopRequested()
    {
        if (StopRequested != null) StopRequested(this, new EventArgs());
    }

    public void StopAllWorkers()
    {
        OnStopRequested();
    }

    public Worker CreateWorker<T>()
        where T: Worker
    {
        var worker = new T(this);
        return worker;
    }
}

class abstract Worker: IDisposable
{
    public Worker(IStopNotifier stopNotifier)
    {
        stopNotofier.StopRequested += HandleStopRequested;
    }

    private IStopNotifier m_stopNotifier;
    private bool m_stopRequested = false;

    internal void HandleStopRequested(object sender, EventArgs e)
    {
        m_stopRequested = true;
    }

    public void Dispose()
    {
        m_stopNotifier.StopRequested -= HandleStopRequested;
    }
}
jrista