我正在注册UserControl的事件,每次移动滚动条时都会抛出此事件(这意味着我们将收到很多事件)。不幸的是,当用户完成使用滚动条(== MouseUp)时,我们没有事件通知。
我们决定实施一种机制,只有在300毫秒后我们才从滚动条接收到任何新通知时才更新我们的模型。
我可以看到如何使用Timer执行此操作并在每次ScrollBar事件发生时重置计时器。
我想知道是否有办法用Linq和Delay做到这一点?
private Action _actionOnMoved;
private void OnScrollBarMoved(object sender, EventArgs args){
}
修改
我已经阅读了可能重复的答案,但节流与我所要求的不同。就我而言,即使我的活动时间少于指定时间,我也不想做任何事情(甚至不是第一次),因为应用此更改需要3-5秒才能完成检索。
所以有所不同:
例如,如果每100毫秒触发一次此事件,并且延迟时间为300毫秒,我希望永远不会调用我的方法。
答案 0 :(得分:1)
您可以将事件处理程序包装到以下
中object _lock = new object();
SomeEvent += (s, e) =>
{
lock(_lock)
{
Monitor.PulseAll(_lock); // pulse any (if any) awaiting events
if(!Monitor.Wait(_lock, 5000)) // delay
{
... // call event handler
// we are here if timeout is expired
}
}
}
未经测试,但这是一个想法:当收到事件时,您开始等待脉冲或超时。如果脉冲来了(意味着接收到另一个事件),那么你只需退出。如果发生超时(表示没有其他事件发生),则调用事件处理程序。
注意:它不是异步的,事件调用者(调用或SomeEvent
)将在延迟期间被阻止。您可能需要将lock
打包到Task.Run
:
SomeEvent += (s, e) => Task.Run(() =>
{
... // the rest of code
}
但是这会在某个其他线程中引发事件处理程序,所以你可能需要调度(调用)到你需要的线程中。
答案 1 :(得分:0)
使用while
循环和ThreadPool
来监控事件。
class MyForm : Form {
private volatile bool mouseWheelHandling = false;
private UserControl userControl;
public void Form_Load(){
// userControl.Scroll
userControl.MouseWheel += (s, a) => {
if(!mouseWheelHandling) { // capture MouseWheel and Scroll events, only handle 1 times.
mouseWheelHandling = true;
ThreadPool.QueueUserWorkItem(_=>{
var horizontalScroll = userControl.HorizontalScroll.Value;
while(true) {
Thread.Sleep(100);
if(horizontalScroll == userControl.HorizontalScroll.Value) {
// Control.Invoke to handle cross-thread action
// do action
mouseWheelHandling = false; // reset the flag
break;
}
horizontalScroll = userControl.HorizontalScroll.Value;
}
});
}
}
}
}
答案 2 :(得分:0)
我的确使用Sinatr的修改版本答案结束了:
public static EventHandler CreateDelayedEventHandler(EventHandler<EventArgs> handler, TimeSpan delay)
{
object lockObject = new object();
return (s, e) =>
{
Task.Run(() =>
{
lock (lockObject)
{
Monitor.PulseAll(lockObject);
if (!Monitor.Wait(lockObject, delay))
{
handler(s, e);
}
}
});
};
}
我现在唯一的疑问是创造了多少任务才可能无所作为。