【问题标题】:Propagating a "volatile" property传播“易失性”属性
【发布时间】:2010-12-13 06:39:11
【问题描述】:

我之所以使用“volatile”是因为它只是含糊其辞。

我有一个类,它有一个名为StopRequested 的属性。该标志可以随时由其他线程设置,并且需要向我的代码指示它应该停止正在执行的操作并退出(这是一个基于 Windows 服务的进程,当调用 Stop 时,所有处理都需要清理并停止)。

我希望创建一些其他类来执行实际的处理工作,但是这些类也必须注意“停止”标志。您不能只传递标志,因为它将传递一个副本,并且您不能将属性作为ref 类型传递。

那么如何将随时可能更改的属性传播到其他类中呢?

我唯一能想到的就是传递对父类的引用,但我不喜欢将工作类与父类耦合以获取一个标志。任何建议将不胜感激。

编辑:

这是一个基本的例子:

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)
        {
            ....
        }
    }
}

【问题讨论】:

  • 请注意,.NET 4 附带了一个专门为此构建的类:CancellationTokenSource,它分发了 CancellationToken,您将其分发给您的工作人员。

标签: c# oop properties


【解决方案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;
    }
}

【讨论】:

  • 我喜欢这个。干净整洁/
【解决方案2】:

就像鲁本斯所说,使用事件。您所描述的基本上将事件定义为 T:

将属性更改传播到其他类。

.NET 中实际上已经提供了一个工具,尽管是以一种通用的方式:INotifyPropertyChanged。这个接口提供了一个单一的事件,PropertyChanged,它允许一个类通知任何监听器任何属性的变化。

在您的情况下,您可以轻松地提供自己的更具体的界面:

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

【讨论】:

    【解决方案3】:

    为什么不创建一个事件来处理停止请求?

    【讨论】:

    • 这是一种选择,我也考虑过,但总的来说,停止机制是一个标志,而不是一个事件。事件表明您可以强制停止,而标志只是“有机会时停止”类型的交易。我只是不认为语义需要事件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-18
    • 2015-07-24
    • 2014-02-12
    • 2017-10-01
    • 1970-01-01
    相关资源
    最近更新 更多