我有兴趣创建一个事件处理对象,您可以只订阅一次执行,然后动作自动取消订阅
.NET中是否有类似的本机功能? 这对我现在有用:
public class CustomTimer
{
private event Action OneSecond;
private readonly Timer timer;
// Registered actions that should be called only once
private readonly ICollection<Action> oneOffs;
public CustomTimer()
{
this.timer = new Timer { Interval = 1000 };
this.timer.Elapsed += this.OnOneSecond;
this.oneOffs = new HashSet<Action>();
}
public bool IsRunning => this.timer.Enabled;
public void Start()
{
this.timer.Start();
}
public void Stop()
{
this.timer.Stop();
}
public void Subscribe(Action callback)
{
this.OneSecond += callback;
}
public void SubscribeOnce(Action callback)
{
this.oneOffs.Add(callback);
this.Subscribe(callback);
}
public void Unsubscribe(Action callback)
{
this.OneSecond -= callback;
this.oneOffs.Remove(callback);
}
protected virtual void OnOneSecond(object sender, ElapsedEventArgs elapsedEventArgs)
{
this.OneSecond?.Invoke();
this.UnsubscribeOneOffs();
}
private void UnsubscribeOneOffs()
{
if (this.oneOffs.Count > 0)
{
foreach (var action in this.oneOffs)
{
this.OneSecond -= action;
}
this.oneOffs.Clear();
}
}
}
此处事件设置为每秒执行一次。
如何在其他不可预测的触发事件的对象中使用类似的策略 并在 UnsubscribeOneOffs()方法运行时阻止事件执行。 我应该使用某种锁?
答案 0 :(得分:1)
无需将一次操作注册为OneSecond事件处理程序。只需将它们保存在单独的列表中即可。
public class CustomTimer
{
List<Action> _oneTimeActions = new List<Action>();
public void SubscribeOnce(Action handler)
{
lock(_oneTimeActions)
{
_oneTimeActions.Add(handler);
}
}
protected virtual void OnOneSecond(object sender, ElapsedEventArgs elapsedEventArgs)
{
// get a local copy of scheduled one time items
// removing them from the list.
Action[] oneTimers;
lock(_oneTimeActions)
{
oneTimers = _oneTimeActions.ToArray();
_oneTimeActions.Clear();
}
// Execute periodic events first
this.OneSecond?.Invoke();
// Now execute one time actions
foreach(var action in oneTimers)
{
action();
}
}
}