一旦发生火灾时的属性或变量的变化值 [英] Fire event when a property or variable changes value

查看:298
本文介绍了一旦发生火灾时的属性或变量的变化值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

欲更多的功能添加至项目我有,使用的若干封装在.NET框架类。这些相同的类提供了一些可以是适应我的项目的功能非常有用的属性,但是有一件事是,这些类缺少的是活动。

I want to add more functionality to a project I have that makes use a number of classes packaged in the NET Framework. These same classes provide a number of properties which can be quite useful adapting the functionality of my project, however one thing that these classes lack is Events.

如果每个属性有一个这将触发每当这种属性的值改为相应的事件,我可以然后分配将采取行动基于这些属性值的事件处理程序。

If each property had a appropriate event that would fire whenever the value of such property changed, I could then assign a event handler that would act based on those properties value.

我波纹管做了一个样本案例,来说明我能想到过的最简单的方法我的目标

I made a sample case bellow to illustrate my goal in the most simpler way I could think off.

样品箱:

System.Net.Sockets.Socket 类(的在MSDN文档)插座有一个名为属性
连接如果套接字连接到指定的终点否则返回false
基本上返回true。

The System.Net.Sockets.Socket class (Socket on MSDN Docs) has a property named Connected that basically returns true if the socket is connected to a specified end point otherwise returns false.

我想做到的是简单的。我想保留下的监视,当它的价值变化,触发一个事件这个
属性。

What I would like to accomplish is simple. I would like to keep this property under "watch" and when the value of it changes, fire a event.

这样做我自己的一个类虽然有点无聊使用的 INotifyPropertyChanged接口,只是因为始终是我的代码更改属性的值,我将不得不手动触发事件。不幸的是,我所知的,甚至没有这种程序可以应用到.NET框架范围内发行的现有的插座类。

Doing that to one of my own classes it would be simple although a bit tiresome using the INotifyPropertyChanged interface, simply because always that my code changed the value of the property I would have to fire the event manually. Unfortunately, to best of my knowledge, not even this kind of procedure can be applied to the existing Socket class distributed within NET Framework.

那么,这个问题变得相当广泛,很抱歉,但我希望它给了一个了解我的目标。

Well, this question is becoming quite extensive, sorry, but I hope it gave an insight to my goal.

现在只是把它,我想看插座的连接属性类,当它的价值变化,触发事件。如果有可能也使用这种方法来观察变量以及性能,这将是真棒,不只是我,但大家谁碰到这个问题蹒跚而行左右。

Now simply putting it, I want to watch the Connected property of the Socket class and when the value of it changes, fire an event. And if it would be possible to also use such approach to watch variables as well properties, it would be awesome, not just for me, but for everyone who stumbles across this question on SO.

一个简单而轻量级的方法是首选,当然,但最重要的,我想了解它是如何完成的,所以在未来我能大规模应用它的其他类。

A simple and lightweight approach is preferred of course, but most of all, I want to understand how it can be done, so in the future I can apply it in mass scale to other classes.

我意识到,我问了很多。非常感谢。

I realize I'm asking a lot. Many thanks.

的任何问题,只是问。

推荐答案

我实现了应该让你开始一个基本的类。我敢肯定,一个全功能的,生产就绪,线程安全类将需要一些更多的工作,再加上你需要实现你自己的时候轮询价值变动策略。

I implemented a basic class that should get you started. I'm sure a fully functional, production-ready, thread-safe class would require a bit more work, plus you need to implement your own strategy for when to poll for value changes.

public class TargettedObserver<T>
{
    private static readonly EqualityComparer<T> EqualityComparer = EqualityComparer<T>.Default;

    private Func<T> ValueTarget;
    private T OldValue;

    public event ObservedValueChangedEventHandler<T> ValueChanged;

    public TargettedObserver(Func<T> valueTarget)
    {
        this.ValueTarget = valueTarget;
        OldValue = ObtainCurrentValue();
    }

    public bool CheckValue()
    {
        T oldValue = OldValue;
        T newValue = ObtainCurrentValue();

        bool hasValueChanged = CompareValues(oldValue, newValue);

        if (hasValueChanged)
        {
            OldValue = newValue;
            NotifyValueChanged(oldValue, newValue);
        }

        return hasValueChanged;
    }

    private void NotifyValueChanged(T oldValue, T newValue)
    {
        var valueChangedEvent = ValueChanged;
        if (valueChangedEvent != null)
            valueChangedEvent(this, new ObservedValueChangedEventArgs<T>(oldValue, newValue));
    }

    private static bool CompareValues(T oldValue, T newValue)
    {
        return !EqualityComparer.Equals(oldValue, newValue);
    }

    private T ObtainCurrentValue()
    {
        return ValueTarget();
    }
}

和事件处理:

public class ObservedValueChangedEventArgs<T> : EventArgs
{
    public T OldValue { get; private set; }
    public T NewValue { get; private set; }

    public ObservedValueChangedEventArgs(T oldValue, T newValue)
    {
        this.OldValue = oldValue;
        this.NewValue = newValue;
    }
}

public delegate void ObservedValueChangedEventHandler<T>(TargettedObserver<T> observer, ObservedValueChangedEventArgs<T> eventArgs);



用法看起来是这样的:

Usage looks something like this:

public class TestClass
{
    private Socket MySocket;
    private static TargettedObserver<bool> SocketConnectedObserver;

    public void Main()
    {
        MySocket = new Socket();
        SocketConnectedObserver = new TargettedObserver<bool>(() => MySocket.Connected);
        SocketConnectedObserver.ValueChanged += ReportSocketConnectedStateChanged;
        PerformSocketConnection();

        MainThread.Invoke(PollSocketValue);
    }

    private void PollSocketValue()
    {
        SocketConnectedObserver.CheckValue();
        MainThread.Invoke(PollSocketValue);
    }

    private void ReportSocketConnectedStateChanged(TargettedObserver<bool> observer, ObservedValueChangedEventArgs<bool> eventArgs)
    {
        Console.WriteLine("Socket connection state changed!  OldValue: " + eventArgs.OldValue + ", NewValue: " + eventArgs.NewValue);
    }
}



注意构造函数接受一个简单的lambda表达式可以计算你想观察值。

Notice the constructor takes a simple lambda expression that can evaluate the value you're wanting to observe.

另外请注意, MainThread.Invoke 只是一个伪代码,以显示它轮询每个主线程循环的变化。我敢肯定,例如,有更好的策略(后台线程与计时器的时间间隔),可以在一个不错的,可重用的方式来实现。还更工作在注销观察者的角度来完成的。很可能使一些漂亮的工厂方法或lambda的代表,所以你不需要保持TargettedObserver实例,漂浮,减少布线/手动代码量。但至少,这应该是一个开始。

Also note that MainThread.Invoke is just a pseudocode to show it polling for a change on every main thread loop. I'm sure there are nicer strategies (background thread with a timer interval) for example that could be implemented in a nice, reusable way. Still more work to be done in terms of deregistering the observer. Could probably make some nice factory methods or lambda delegates so you don't need to keep the TargettedObserver instance floating around and reduce the amount of wiring/manual code. But at least this should be a start.

这篇关于一旦发生火灾时的属性或变量的变化值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆