use*_*847 9 c# system.reactive c#-5.0 windows-8 windows-runtime
我想限制事件的速度,如何在不使用Microsoft Rx框架的情况下实现这一目标.我在Rx的帮助下做到了这一点.但我正在尝试的是,我需要根据时间段限制Map的View更改事件.是否可以在不使用Rx的情况下实现相同的功能.
我不允许使用Rx,我必须保持二进制大小尽可能小.
Jam*_*rld 16
如果您的事件是类型的,那么这是有效的EventHandler<EventArgs>.它为受限制的事件处理程序创建一个包装器:
private EventHandler<EventArgs> CreateThrottledEventHandler(
EventHandler<EventArgs> handler,
TimeSpan throttle)
{
bool throttling = false;
return (s,e) =>
{
if(throttling) return;
handler(s,e);
throttling = true;
Task.Delay(throttle).ContinueWith(_ => throttling = false);
};
}
Run Code Online (Sandbox Code Playgroud)
像这样附上:
this.SomeEvent += CreateThrottledEventHandler(
(s,e) => Console.WriteLine("I am throttled!"),
TimeSpan.FromSeconds(5));
Run Code Online (Sandbox Code Playgroud)
虽然,CreateThrottledEventHandler如果您需要-=稍后将其解除,则应该存储从中返回的处理程序.
BTo*_*TKD 15
我相信在'throttled'事件处理程序中,以下要求是必不可少的:
考虑到这些要求,以前接受的答案并不令人满意; 它正确地满足了前两个要求,但并不能保证最终会引发最后一个事件.我认为这一点特别重要,因为以高频率提出的事件通常代表"状态变化"和/或"用户请求"; 我们总是希望收到有关状态或用户交互更改的最新更新.
为了满足所有这些要求,我创建了自己的通用"ThrottledEventHandler"类.
public class ThrottledEventHandler<TArgs>
where TArgs : EventArgs
{
private readonly EventHandler<TArgs> _innerHandler;
private readonly EventHandler<TArgs> _outerHandler;
private readonly Timer _throttleTimer;
private readonly object _throttleLock = new object();
private Action _delayedHandler = null;
public ThrottledEventHandler(EventHandler<TArgs> handler, TimeSpan delay)
{
_innerHandler = handler;
_outerHandler = HandleIncomingEvent;
_throttleTimer = new Timer(delay.TotalMilliseconds);
_throttleTimer.Elapsed += Timer_Tick;
}
private void HandleIncomingEvent(object sender, TArgs args)
{
lock (_throttleLock)
{
if (_throttleTimer.Enabled)
{
_delayedHandler = () => SendEventToHandler(sender, args);
}
else
{
SendEventToHandler(sender, args);
}
}
}
private void SendEventToHandler(object sender, TArgs args)
{
if (_innerHandler != null)
{
_innerHandler(sender, args);
_throttleTimer.Start();
}
}
private void Timer_Tick(object sender, EventArgs args)
{
lock (_throttleLock)
{
_throttleTimer.Stop();
if (_delayedHandler != null)
{
_delayedHandler();
_delayedHandler = null;
}
}
}
public static implicit operator EventHandler<TArgs>(ThrottledEventHandler<TArgs> throttledHandler)
{
return throttledHandler._outerHandler;
}
}
Run Code Online (Sandbox Code Playgroud)
用法看起来像这样:
myObject.MyFrequentlyRaisedEvent += new ThrottledEventHandler(MyActualEventHandler, TimeSpan.FromMilliseconds(50));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3516 次 |
| 最近记录: |