C# 有没有办法防止事件处理程序自行触发?

C# 有没有办法防止事件处理程序自行触发?,c#,events,C#,Events,我有一个事件处理程序,用于处理可以快速连续发生的事件。在某些情况下,当事件再次触发时(毫秒内),处理程序仍将执行 有没有办法让这些处理程序…串行化?那么,在事件调用#1完成之前,事件调用#2无法启动 如果这是一个糟糕的想法,为什么?这是一个在后台无人值守地运行的批处理过程,因此我并不十分担心一个调用阻塞另一个调用时可能出现的性能问题。使用多线程控制锁定。这可以防止代码在同一时刻多次运行 已编辑 例如: 有几个选项可以序列化事件的处理,这些事件可以从多个线程并发触发,也可以通过重新注册/递归在同一

我有一个事件处理程序,用于处理可以快速连续发生的事件。在某些情况下,当事件再次触发时(毫秒内),处理程序仍将执行

有没有办法让这些处理程序…串行化?那么,在事件调用#1完成之前,事件调用#2无法启动


如果这是一个糟糕的想法,为什么?这是一个在后台无人值守地运行的批处理过程,因此我并不十分担心一个调用阻塞另一个调用时可能出现的性能问题。

使用多线程控制
锁定
。这可以防止代码在同一时刻多次运行

已编辑
例如:


有几个选项可以序列化事件的处理,这些事件可以从多个线程并发触发,也可以通过重新注册/递归在同一线程上触发

其中一个选项是使用任务调度器。在您的场景中,任务调度器的目的是将回调排队,以便稍后串行执行。这类任务调度器的一个众所周知的概念性示例是WinForms消息循环(从
应用程序.Run
开始,使用
控件.BeginInvoke
排队)和WPF调度程序循环(从
调度程序.Run
开始,使用
调度程序.BeginInvoke
调度程序.InvokeAsync>排队)

Stephen Toub对任务调度器的实现知之甚少,但非常有用。我发布了一些基于它的代码(后一个是来自一个密切相关的问题,)

此处描述了另一个选项:


在这种情况下,处理程序是作为任务组成的,每个新处理程序都是在前一个任务完成后启动的。

但是我应该锁定什么?整个物体?我可以“锁定”一个方法(事件处理程序本身)吗。因此,您可以将任何对象放在其中,因为该对象实际上只是代码块正在使用的标志,对吗?如果处理程序在线程池上运行,那么在锁定池中的所有线程时要小心死锁是的。但是锁只对真正相同的对象起作用,也就是我将_lockKey写为static!如果事件代码本身再次触发同一线程上的事件,则会发生这种情况,因为它已经获得了锁,可以在不重新锁定的情况下重新进入。这听起来有些牵强,但在UI事件中非常常见,例如在
TextBox.TextChanged
事件中更改
Text
时。作为备注,您需要有喘息的空间,否则如果要堆叠它们,最终可能会耗尽资源。事件处理程序是否在多个线程上运行?如果不是,事件处理程序是否正在执行某种DoEvents调用以创建重入性?如果没有,这怎么可能?通过泵送消息队列触发事件处理程序;如果线程忙于运行事件处理程序,那么根据定义,它并不忙于抽取队列!
public class Foo
{
    private static object _lockKey = new object();

    private void YourEventHandlerMethod(object sender, EventArgs e)
    {   
        lock (_lockKey)
        {
            // the code you put inside this block will be execute only
            // once at time.

            // If a second call has the intention to use this block before
            // the conclusion of the first call, the second call (the thread)
            // will be put in hold.
        }
    }
}