Распространение «изменчивого» свойства

2

Я ставлю "изменчивым", потому что это только смутно.

У меня есть класс, который имеет свойство StopRequested. Этот флаг может быть установлен другими потоками в любое время и должен указать моему коду, что он должен остановить то, что он делает, и выйти (это процесс на основе Windows, и когда вызывается Stop, вся обработка должна очищать и остановки).

Я хочу создать некоторые другие классы, чтобы выполнить основной труд обработки, однако эти классы также должны знать о флаге "stop". Вы не можете просто передать флаг, потому что он будет передавать копию, и вы не можете передавать свойства как ref.

Итак, как вы распространяете свойство, которое может быть изменено в любое время на другие классы?

Единственное, о чем я могу думать, это передать ссылку на родительский класс, но мне не нравится связывать рабочие классы с родителем для одного флага. Любые предложения будут оценены.

EDIT:

Вот базовый пример:

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)
        {
            ....
        }
    }
}
  • 0
    Просто отметим, что .NET 4 поставляется с специально созданным классом для этого: CancellationTokenSource , который выдает CancellationToken который вы распространяете среди своих работников.
Теги:
oop
properties

3 ответа

1
Лучший ответ

У каждого из ваших рабочих классов есть собственное свойство StopRequest, а затем просто установите это значение, если отмечен флаг StopRequest.

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


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

        foreach (var child in WorkerClasses)
            child.StopRequest = value;
    }
}
  • 0
    Мне это нравится. Красиво и чисто /
1

Как сказал Рубенс, используйте событие. То, что вы описали, в основном определяет событие на T:

Распространение изменений свойств на другие классы.

В .NET есть средство, которое предоставляет это уже, хотя и в общем виде: INotifyPropertyChanged. Этот интерфейс предоставляет одно событие, свойствоChanged, которое позволяет классу уведомлять слушателей о любых изменениях свойств.

В вашем случае вы можете легко предоставить свой собственный интерфейс, что более конкретно:

interface IStopNotifier
{
    event EventHandler StopRequested;
}

Этот интерфейс будет реализован вашим основным рабочим менеджером (каким бы он ни был) и мог бы распространяться так:

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;
    }
}
0

Почему бы не создать событие для обработки запросов на остановку?

  • 0
    Это один из вариантов, и я его рассмотрел, но в целом механизм остановки - это флаг, а не событие. Событие будет означать, что вы можете форсировать остановку, а флаг - это просто сделка «Стоп, когда вы получаете шанс». Я просто не думаю, что семантика требует события.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню