1

我正在处理进程的退出事件。我有一个用于该事件的进程的复选框,它确定运行 Exited 事件时会发生什么。如果我在进程运行时选中复选框,它将获取进程并添加退出事件。如果进程没有运行,它会启动进程并添加 Exited 事件。如果未选中该复选框,则无论进程是否正在运行,我什么都不做。

我的问题是,如果进程正在运行并且我选中该框(它得到一个事件),取消选中该框(设计没有发生任何事情),然后重新选中该框,那么该进程将获得两个退出事件(它们完全相同方法)。如果我有 Process 对象,如果它已经有一个 Exited 事件,我怎么能不添加它?

4

5 回答 5

2

根据此 Microsoft 论坛帖子http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/45071852-3a61-4181-9a25-068a8698b8b6/您可以在再次分配之前删除现有处理程序.

于 2013-05-28T21:22:30.273 回答
1

您将事件与-=操作员的委托分离。

就像您将事件绑定到委托一样:

EventHandler foo = new EventHandler(this._onClick)
myButton.Click += foo;

如果您将该参考保存在某处,您也可以这样做:

myButton.Click -= foo;

然后当事件被触发时,它不再调用 foo.

当复选框被选中时,您可能正在做的事情是这样的:

foo.Exited += new EventHandler(your_method);

这样,每次您选中该框时,您都会获得一个与该事件相关联的新处理程序。只使用一个处理程序。这样,当复选框未选中时,您可以-=将之前关联到退出事件的委托。

编辑:既然你想要的只是保持委托引用的方法不做任何事情,为什么不在检查事件之外的某个时刻将委托绑定到事件,然后在方法中使用复选框状态选择是运行该方法的其余部分还是提前返回停止它?

于 2013-05-28T21:13:54.913 回答
1

要获取订阅邀请的所有代表的数组,只需使用该GetInvoacationList方法。从那里您可以检查它的长度或对其进行迭代以检查事件将调用多少/哪些委托。

 Delegate[] delegates = MyEvent.GetInvocationList();

根据您实际尝试做的事情,您似乎可以做类似的事情;

  if (MyEvent.GetInvocationList().Length > 0)

或者

 if (MyEvent.GetInvoationList().Contains(referenceToMyDelegate))
于 2013-05-28T21:17:17.243 回答
0

如果您必须查看事件,您可以使用反射:

class Program
{
    static void Main(string[] args)
    {
        var car = new Car();
        car.Stopped += car_Stopped;
        var evt = car.GetType().GetEvent("Stopped");
        if(evt == null) //evt will be null if nothing is registered to the event
            car.Stopped += car_Stopped;

        car.Stop(); //Prints 'Stopped!' only once

        Console.ReadLine();
    }

    static void car_Stopped(object sender, EventArgs e)
    {
        Console.WriteLine("Stopped!");
    }
}

class Car
{
    public event EventHandler<EventArgs> Stopped;
    protected void OnStopped()
    {
        var temp = Stopped;
        if(temp != null)
            Stopped(this, new EventArgs());
    }
    public void Stop()
    {
        OnStopped();
    }
}
于 2013-05-28T21:26:38.887 回答
0

尝试这个:

delegate void MyDelegate(string message);

class Foo
{
    MyDelegate _delegate = null;
    int _count = 0;

    public event MyDelegate MySingleDelegateEvent
    {
        add
        {
            if (_count == 0)
            {
                _delegate += value;
                _count++;
            }
        }
        remove
        {
            if (_delegate != null)
            {
                _delegate -= value;
                _count--;
            }
        }
    }
}
于 2013-05-28T21:24:28.283 回答