我实现了一个应该让你开始的基本类。我敢肯定,一个功能齐全、生产就绪、线程安全的类需要做更多的工作,而且您需要实施自己的策略来确定何时轮询值更改。
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);
用法如下所示:
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 表达式,可以计算您想要观察的值。
另请注意,这MainThread.Invoke
只是一个伪代码,显示它轮询每个主线程循环的更改。例如,我确信有更好的策略(具有计时器间隔的后台线程)可以以一种很好的、可重用的方式实现。在注销观察者方面还有更多工作要做。可能会创建一些不错的工厂方法或 lambda 委托,因此您不需要保持 TargettedObserver 实例浮动并减少接线/手动代码的数量。但至少这应该是一个开始。