c#禁用事件一段时间

c#禁用事件一段时间,c#,events,timer,pause,C#,Events,Timer,Pause,我使用这组函数注销事件列表框1\u SelectedValueChanged一段时间 函数名为:Pause() 作为一个函数,是否有任何方法可以对各种事件执行相同的操作,例如: 暂停(列表框1.SelectedValueChanged) 或 暂停(按钮1.单击) 等等 我会使用一个DateTime字段。我会签入SelectedValuedChanged(),即使它被允许运行。(不要注销事件) 例如:(伪) 更新2: public partial class Form1 : Form {

我使用这组函数注销事件列表框1\u SelectedValueChanged一段时间

函数名为:Pause()

作为一个函数,是否有任何方法可以对各种事件执行相同的操作,例如:

暂停(列表框1.SelectedValueChanged)

暂停(按钮1.单击)

等等


我会使用一个
DateTime
字段。我会签入
SelectedValuedChanged()
,即使它被允许运行。(不要注销事件)

例如:(伪)



更新2:

public partial class Form1 : Form
{
    private TimeEnabledEvent _event = new TimeEnabledEvent();

    public Form1()
    {
        InitializeComponent();
        listBox1.SelectedValueChanged += _event.Check(ListBox1_SelectedValueChanged);
        _event.Pause(1000);
    }

    private void ListBox1_SelectedValueChanged(object sender, EventArgs e)
    {
        // do your thing
    }
}


我会使用微软的反应式框架——NuGet“System.Responsive”——然后您可以这样做:

bool pause = false;

IObservable<EventPattern<EventArgs>> observable =
    Observable
        .FromEventPattern<EventHandler, EventArgs>(
            h => listBox1.SelectedIndexChanged += h,
            h => listBox1.SelectedIndexChanged -= h)
        .Where(ep => pause != true);

IDisposable subscription =
    observable
        .Subscribe(ep => listBox1_SelectedValueChanged(ep.Sender, ep.EventArgs));
bool pause=false;
可观测=
可观察
.FromEventPattern(
h=>listBox1.SelectedIndexChanged+=h,
h=>listBox1.SelectedIndexChanged-=h)
。其中(ep=>暂停!=真);
IDisposable订阅=
可观察
.Subscribe(ep=>listBox1_SelectedValueChanged(ep.Sender,ep.EventArgs));
现在只需将
pause
的值从
false
更改为
true
即可暂停事件处理


当您想要分离处理程序时,只需调用
subscription.Dispose()

我会使用
WaitHandle
来完成此操作,例如
ManualResetEvent
。如果要独立挂起多个事件,我会使用不同的
ManualResetEvent
s

我会这样实现它:

public class Class1
{
    private TimeEnabledEvent _selectedValueChanged = new TimeEnabledEvent();

    public Class1()
    {
        listBox1.SelectedValueChanged += (s, e) =>
        {
            if (_selectedValueChanged.IsEnabled)
                listBox1_SelectedValueChanged(s, e);
        };


        _selectedValueChanged.Pause(200);
    }


    public void listBox1_SelectedValueChanged(object sender, EventArgs e)
    {
        // do your thing.
    }

}
private ManualResetEvent pauseListBox1;
private ManualResetEvent pauseButton1;
public event SomeDelegate MyEvent;
要开始暂停,我将使用:

pauseListBox1.Set();
pauseListBox1.Reset();
要结束暂停,我将使用:

pauseListBox1.Set();
pauseListBox1.Reset();
在事件处理程序中,我将使用

// Return from the event handler of the even is set
if (WaitHandle.WaitOne(1))
    return;

我将具体回答您一般如何做到这一点。如何改进暂停程序本身已经得到了回答

确实,您不能将事件引用传递给另一个方法,但您可以通过一点反射来实现这一点。比如说

private static void Pause<TSource, TEvent>(TSource source, Expression<Func<TSource, TEvent>> eventRef, TEvent handler, int forTime = 200) {
    var ev = source.GetType().GetEvent(((MemberExpression)eventRef.Body).Member.Name);
    // source.eventRef -= handler;
    ev.RemoveMethod.Invoke(source, new object[] { handler });
    // do some stuff
    // source.eventRef += handler;
    ev.AddMethod.Invoke(source, new object[] { handler });
}
不幸的是,只有当事件按如下方式实现时,该方法才有效:

public class Class1
{
    private TimeEnabledEvent _selectedValueChanged = new TimeEnabledEvent();

    public Class1()
    {
        listBox1.SelectedValueChanged += (s, e) =>
        {
            if (_selectedValueChanged.IsEnabled)
                listBox1_SelectedValueChanged(s, e);
        };


        _selectedValueChanged.Pause(200);
    }


    public void listBox1_SelectedValueChanged(object sender, EventArgs e)
    {
        // do your thing.
    }

}
private ManualResetEvent pauseListBox1;
private ManualResetEvent pauseButton1;
public event SomeDelegate MyEvent;
如果它是这样实现的(并且所有winform控件事件都是这样实现的)

它不再工作,因为您无法通过表达式传递此类事件引用。然而,表达式仅用于获取事件名称的方便性。因此,您可以显式传递事件名称:

private static void Pause<TSource, TEvent>(TSource source, string eventName, TEvent handler, int forTime = 200) {
    var ev = source.GetType().GetEvent(eventName);
    // source.eventRef -= handler;
    ev.RemoveMethod.Invoke(source, new object[] { handler });
    // do some stuff
    // source.eventRef += handler;
    ev.AddMethod.Invoke(source, new object[] { handler });
}
private静态无效暂停(TSource-source,string-eventName,TEvent处理程序,int-forTime=200){
var ev=source.GetType().GetEvent(eventName);
//source.eventRef-=处理程序;
Invoke(源,新对象[]{handler});
//做点什么
//source.eventRef+=处理程序;
Invoke(源,新对象[]{handler});
}
然后使用就变成了

Pause<ListBox, EventHandler>(listBox1, nameof(listBox1.SelectedValueChanged), listBox1_SelectedValueChanged);
Pause(列表框1,名称(列表框1.SelectedValueChanged),列表框1\u SelectedValueChanged);
不那么漂亮但仍然有效。

我找到了一种方法(使用了本论坛的一些代码),它可以工作,但有点复杂(好的,可能非常复杂),下面是代码:

用法(暂停一段时间):

用法(在恢复之前抑制):

用法(抑制后-用于恢复):

其余的:

#region Events
public static class Events
{        
    public static void Pause(this Control control, string eventName, int forTime)
    {
        EventTimers et = new EventTimers();
        et.PauseEvent(control, eventName, forTime);
    }

    public static void Pause(this Control control, int forTime)
    {
        EventTimers et1 = new EventTimers();
        et1.PauseEvent(control, forTime);
    }

    public static cEventSuppressor Suppress(this Control control, string eventName)
    {
        cEventSuppressor newControl = null;
        newControl = new cEventSuppressor(control);
        newControl.Suppress(eventName);
        return newControl;
    }
    public static cEventSuppressor Suppress(this Control control)
    {
        cEventSuppressor newControl = null;
        newControl = new cEventSuppressor(control);
        newControl.Suppress();
        return newControl;
    }
}

public class EventTimers
{             
    private System.Windows.Forms.Timer disableEvent = new System.Windows.Forms.Timer();
    private cEventSuppressor suppressedControl { get; set; }

    private static string eventName { get; set; }

    //Pause specific Event
    public void PauseEvent(Control control, string eventName, int forTime)
    {
        suppressedControl = new cEventSuppressor(control);
        suppressedControl.Suppress(eventName);          

        disableEvent.Tick += new EventHandler(disableEvent_Tick);
        disableEvent.Interval = (forTime);
        disableEvent.Enabled = true;
        disableEvent.Start();
    }
    private void disableEvent_Tick(object sender, EventArgs e)
    {
        if (disableEvent.Enabled == true)
        {
            disableEvent.Tick -= new EventHandler(disableEvent_Tick);
            disableEvent.Stop();
            disableEvent.Enabled = false;

            suppressedControl.Resume(eventName);
        }
    }

    //Pause All Events
    public void PauseEvent(Control control, int forTime)
    {
        suppressedControl = new cEventSuppressor(control);
        suppressedControl.Suppress();

        disableEvent.Tick += new EventHandler(disableEvent_Tick2);
        disableEvent.Interval = (forTime);
        disableEvent.Enabled = true;
        disableEvent.Start();
    }
    private void disableEvent_Tick2(object sender, EventArgs e)
    {
        if (disableEvent.Enabled == true)
        {
            disableEvent.Tick -= new EventHandler(disableEvent_Tick2);
            disableEvent.Stop();
            disableEvent.Enabled = false;

            suppressedControl.Resume();
        }
    }

}    
public class cEventSuppressor
{
    Control _source;
    EventHandlerList _sourceEventHandlerList;
    FieldInfo _headFI;
    Dictionary<object, Delegate[]> suppressedHandlers = new Dictionary<object, Delegate[]>();
    PropertyInfo _sourceEventsInfo;
    Type _eventHandlerListType;
    Type _sourceType;

    public cEventSuppressor(Control control)
    {
        if (control == null)
            throw new ArgumentNullException("control", "An instance of a control must be provided.");

        _source = control;
        _sourceType = _source.GetType();
        _sourceEventsInfo = _sourceType.GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
        _sourceEventHandlerList = (EventHandlerList)_sourceEventsInfo.GetValue(_source, null);
        _eventHandlerListType = _sourceEventHandlerList.GetType();
        _headFI = _eventHandlerListType.GetField("head", BindingFlags.Instance | BindingFlags.NonPublic);
    }
    private Dictionary<object, Delegate[]> BuildList()
    {
        Dictionary<object, Delegate[]> retval = new Dictionary<object, Delegate[]>();
        object head = _headFI.GetValue(_sourceEventHandlerList);
        if (head != null)
        {
            Type listEntryType = head.GetType();
            FieldInfo delegateFI = listEntryType.GetField("handler", BindingFlags.Instance | BindingFlags.NonPublic);
            FieldInfo keyFI = listEntryType.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic);
            FieldInfo nextFI = listEntryType.GetField("next", BindingFlags.Instance | BindingFlags.NonPublic);
            retval = BuildListWalk(retval, head, delegateFI, keyFI, nextFI);
        }
        return retval;
    }

    private Dictionary<object, Delegate[]> BuildListWalk(Dictionary<object, Delegate[]> dict,
                                object entry, FieldInfo delegateFI, FieldInfo keyFI, FieldInfo nextFI)
    {
        if (entry != null)
        {
            Delegate dele = (Delegate)delegateFI.GetValue(entry);
            object key = keyFI.GetValue(entry);
            object next = nextFI.GetValue(entry);

            if (dele != null)
            {
                Delegate[] listeners = dele.GetInvocationList();
                if (listeners != null && listeners.Length > 0)
                {
                    dict.Add(key, listeners);
                }
            }
            if (next != null)
            {
                dict = BuildListWalk(dict, next, delegateFI, keyFI, nextFI);
            }
        }
        return dict;
    }
    public void Resume()
    {
        Resume(null);
    }
    public void Resume(string pMethodName)
    {
        //if (_handlers == null)
        //    throw new ApplicationException("Events have not been suppressed.");
        Dictionary<object, Delegate[]> toRemove = new Dictionary<object, Delegate[]>();

        // goes through all handlers which have been suppressed.  If we are resuming,
        // all handlers, or if we find the matching handler, add it back to the
        // control's event handlers
        foreach (KeyValuePair<object, Delegate[]> pair in suppressedHandlers)
        {

            for (int x = 0; x < pair.Value.Length; x++)
            {

                string methodName = pair.Value[x].Method.Name;
                if (pMethodName == null || methodName.Equals(pMethodName))
                {
                    _sourceEventHandlerList.AddHandler(pair.Key, pair.Value[x]);
                    toRemove.Add(pair.Key, pair.Value);
                }
            }
        }
        // remove all un-suppressed handlers from the list of suppressed handlers
        foreach (KeyValuePair<object, Delegate[]> pair in toRemove)
        {
            for (int x = 0; x < pair.Value.Length; x++)
            {
                suppressedHandlers.Remove(pair.Key);
            }
        }
        //_handlers = null;
    }
    public void Suppress()
    {
        Suppress(null);
    }
    public void Suppress(string pMethodName)
    {
        //if (_handlers != null)
        //    throw new ApplicationException("Events are already being suppressed.");

        Dictionary<object, Delegate[]> dict = BuildList();

        foreach (KeyValuePair<object, Delegate[]> pair in dict)
        {
            for (int x = pair.Value.Length - 1; x >= 0; x--)
            {
                //MethodInfo mi = pair.Value[x].Method;
                //string s1 = mi.Name; // name of the method
                //object o = pair.Value[x].Target;
                // can use this to invoke method    pair.Value[x].DynamicInvoke
                string methodName = pair.Value[x].Method.Name;

                if (pMethodName == null || methodName.Equals(pMethodName))
                {
                    _sourceEventHandlerList.RemoveHandler(pair.Key, pair.Value[x]);
                    suppressedHandlers.Add(pair.Key, pair.Value);
                }
            }
        }
    }
}
#endregion
#地区事件
公共静态类事件
{        
公共静态无效暂停(此控件,字符串eventName,int-forTime)
{
EventTimers et=新的EventTimers();
et.PauseEvent(控件、事件名、forTime);
}
公共静态无效暂停(此控件,int-forTime)
{
EventTimers et1=新的EventTimers();
et1.暂停事件(控制,forTime);
}
公共静态cEventSuppressor Suppress(此控件,字符串eventName)
{
ceventsuppressornewcontrol=null;
newControl=新cEventSuppressor(控制);
newControl.Suppress(eventName);
返回新控件;
}
公共静态cEventSuppressor抑制(此控件)
{
ceventsuppressornewcontrol=null;
newControl=新cEventSuppressor(控制);
newControl.Suppress();
返回新控件;
}
}
公共类事件计时器
{             
private System.Windows.Forms.Timer disableEvent=new System.Windows.Forms.Timer();
私有cEventSuppressor suppressedControl{get;set;}
私有静态字符串eventName{get;set;}
//暂停特定事件
public void PauseEvent(控件、字符串eventName、int-forTime)
{
抑制控制=新的cEventSuppressor(控制);
suppressedControl.Suppress(事件名称);
disableEvent.Tick+=新的事件处理程序(disableEvent_Tick);
disableEvent.Interval=(forTime);
disableEvent.Enabled=true;
disableEvent.Start();
}
私有void disableEvent_Tick(对象发送方,事件参数e)
{
if(disableEvent.Enabled==true)
{
disableEvent.Tick-=新事件处理程序(disableEvent_Tick);
disableEvent.Stop();
disableEvent.Enabled=false;
suppressedControl.Resume(事件名称);
}
}
//暂停所有事件
公共无效暂停事件(控制,int forTime)
{
抑制控制=新的cEventSuppressor(控制);
suppressedControl.Suppress();
disableEvent.Tick+=新的事件处理程序(disableEvent_Tick2);
disableEvent.Interval=(forTime);
disableEvent.Enabled=true;
disableEvent.Start();
}
私有void disableEvent_Tick2(对象发送方,事件参数e)
{
if(disableEvent.Enabled==true)
{
disableEvent.Tick-=新的事件处理程序(disableEvent_Tick2);
disableEvent.Stop();
disableEvent.Enabled=false;
suppressedControl.Resume();
}
}
}    
公共类cEventSuppressor
{
控制源;
EventHandlerList _sourceEventHandlerList;
FieldInfo(联邦总部);
Dictionary suppressedHandlers=新字典();
PropertyInfo\u sourceEventsInfo;
类型_eventHandlerListType;
类型_sourceType;
公共行政审批人(公司)
listBox1.Pause("listBox1_SelectedValueChanged", 3000);
listBox1.Pause(3000);  // to pause all events of listbox1
button3.Pause("button3_Click", 10000);
cEventSuppressor temp = listBox1.Suppress("listBox1_SelectedValueChanged");
cEventSuppressor temp = listBox1.Suppress(); //to suppress all
temp.Resume("listBox1_SelectedValueChanged");
temp.Resume();  //To resume all
#region Events
public static class Events
{        
    public static void Pause(this Control control, string eventName, int forTime)
    {
        EventTimers et = new EventTimers();
        et.PauseEvent(control, eventName, forTime);
    }

    public static void Pause(this Control control, int forTime)
    {
        EventTimers et1 = new EventTimers();
        et1.PauseEvent(control, forTime);
    }

    public static cEventSuppressor Suppress(this Control control, string eventName)
    {
        cEventSuppressor newControl = null;
        newControl = new cEventSuppressor(control);
        newControl.Suppress(eventName);
        return newControl;
    }
    public static cEventSuppressor Suppress(this Control control)
    {
        cEventSuppressor newControl = null;
        newControl = new cEventSuppressor(control);
        newControl.Suppress();
        return newControl;
    }
}

public class EventTimers
{             
    private System.Windows.Forms.Timer disableEvent = new System.Windows.Forms.Timer();
    private cEventSuppressor suppressedControl { get; set; }

    private static string eventName { get; set; }

    //Pause specific Event
    public void PauseEvent(Control control, string eventName, int forTime)
    {
        suppressedControl = new cEventSuppressor(control);
        suppressedControl.Suppress(eventName);          

        disableEvent.Tick += new EventHandler(disableEvent_Tick);
        disableEvent.Interval = (forTime);
        disableEvent.Enabled = true;
        disableEvent.Start();
    }
    private void disableEvent_Tick(object sender, EventArgs e)
    {
        if (disableEvent.Enabled == true)
        {
            disableEvent.Tick -= new EventHandler(disableEvent_Tick);
            disableEvent.Stop();
            disableEvent.Enabled = false;

            suppressedControl.Resume(eventName);
        }
    }

    //Pause All Events
    public void PauseEvent(Control control, int forTime)
    {
        suppressedControl = new cEventSuppressor(control);
        suppressedControl.Suppress();

        disableEvent.Tick += new EventHandler(disableEvent_Tick2);
        disableEvent.Interval = (forTime);
        disableEvent.Enabled = true;
        disableEvent.Start();
    }
    private void disableEvent_Tick2(object sender, EventArgs e)
    {
        if (disableEvent.Enabled == true)
        {
            disableEvent.Tick -= new EventHandler(disableEvent_Tick2);
            disableEvent.Stop();
            disableEvent.Enabled = false;

            suppressedControl.Resume();
        }
    }

}    
public class cEventSuppressor
{
    Control _source;
    EventHandlerList _sourceEventHandlerList;
    FieldInfo _headFI;
    Dictionary<object, Delegate[]> suppressedHandlers = new Dictionary<object, Delegate[]>();
    PropertyInfo _sourceEventsInfo;
    Type _eventHandlerListType;
    Type _sourceType;

    public cEventSuppressor(Control control)
    {
        if (control == null)
            throw new ArgumentNullException("control", "An instance of a control must be provided.");

        _source = control;
        _sourceType = _source.GetType();
        _sourceEventsInfo = _sourceType.GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
        _sourceEventHandlerList = (EventHandlerList)_sourceEventsInfo.GetValue(_source, null);
        _eventHandlerListType = _sourceEventHandlerList.GetType();
        _headFI = _eventHandlerListType.GetField("head", BindingFlags.Instance | BindingFlags.NonPublic);
    }
    private Dictionary<object, Delegate[]> BuildList()
    {
        Dictionary<object, Delegate[]> retval = new Dictionary<object, Delegate[]>();
        object head = _headFI.GetValue(_sourceEventHandlerList);
        if (head != null)
        {
            Type listEntryType = head.GetType();
            FieldInfo delegateFI = listEntryType.GetField("handler", BindingFlags.Instance | BindingFlags.NonPublic);
            FieldInfo keyFI = listEntryType.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic);
            FieldInfo nextFI = listEntryType.GetField("next", BindingFlags.Instance | BindingFlags.NonPublic);
            retval = BuildListWalk(retval, head, delegateFI, keyFI, nextFI);
        }
        return retval;
    }

    private Dictionary<object, Delegate[]> BuildListWalk(Dictionary<object, Delegate[]> dict,
                                object entry, FieldInfo delegateFI, FieldInfo keyFI, FieldInfo nextFI)
    {
        if (entry != null)
        {
            Delegate dele = (Delegate)delegateFI.GetValue(entry);
            object key = keyFI.GetValue(entry);
            object next = nextFI.GetValue(entry);

            if (dele != null)
            {
                Delegate[] listeners = dele.GetInvocationList();
                if (listeners != null && listeners.Length > 0)
                {
                    dict.Add(key, listeners);
                }
            }
            if (next != null)
            {
                dict = BuildListWalk(dict, next, delegateFI, keyFI, nextFI);
            }
        }
        return dict;
    }
    public void Resume()
    {
        Resume(null);
    }
    public void Resume(string pMethodName)
    {
        //if (_handlers == null)
        //    throw new ApplicationException("Events have not been suppressed.");
        Dictionary<object, Delegate[]> toRemove = new Dictionary<object, Delegate[]>();

        // goes through all handlers which have been suppressed.  If we are resuming,
        // all handlers, or if we find the matching handler, add it back to the
        // control's event handlers
        foreach (KeyValuePair<object, Delegate[]> pair in suppressedHandlers)
        {

            for (int x = 0; x < pair.Value.Length; x++)
            {

                string methodName = pair.Value[x].Method.Name;
                if (pMethodName == null || methodName.Equals(pMethodName))
                {
                    _sourceEventHandlerList.AddHandler(pair.Key, pair.Value[x]);
                    toRemove.Add(pair.Key, pair.Value);
                }
            }
        }
        // remove all un-suppressed handlers from the list of suppressed handlers
        foreach (KeyValuePair<object, Delegate[]> pair in toRemove)
        {
            for (int x = 0; x < pair.Value.Length; x++)
            {
                suppressedHandlers.Remove(pair.Key);
            }
        }
        //_handlers = null;
    }
    public void Suppress()
    {
        Suppress(null);
    }
    public void Suppress(string pMethodName)
    {
        //if (_handlers != null)
        //    throw new ApplicationException("Events are already being suppressed.");

        Dictionary<object, Delegate[]> dict = BuildList();

        foreach (KeyValuePair<object, Delegate[]> pair in dict)
        {
            for (int x = pair.Value.Length - 1; x >= 0; x--)
            {
                //MethodInfo mi = pair.Value[x].Method;
                //string s1 = mi.Name; // name of the method
                //object o = pair.Value[x].Target;
                // can use this to invoke method    pair.Value[x].DynamicInvoke
                string methodName = pair.Value[x].Method.Name;

                if (pMethodName == null || methodName.Equals(pMethodName))
                {
                    _sourceEventHandlerList.RemoveHandler(pair.Key, pair.Value[x]);
                    suppressedHandlers.Add(pair.Key, pair.Value);
                }
            }
        }
    }
}
#endregion