在C#中,如何从一个绑定的委托中暂停执行事件?

时间:2012-06-25 00:34:50

标签: c# .net events

我目前正在使用一个事件来触发一组代理,我需要能够防止剩余的代理从另一个代理中解雇。

以下代码复制了方案......

//nonsense class
public class Foo {
    public string Bar { get; set; }
}

//nonsense event.
public event Action<Foo> SomeEvent;

void BindAndFire() {
    //wire it up.
    SomeEvent += (foo) => { 
        var a = DateTime.Now.Millisecond % 2;
        foo.Bar = (a == 0) ? "Hooray" : "Boo";
    };
    SomeEvent += (foo) => { 
        if(foo.Bar == "Boo") {
            SomeEvent.CANCEL_THE_REST(); //what do I do here?
        }
    };
    SomeEvent += (foo) => { 
        foo.Bar += ", you made it!";
    };

    //fire the event.
    SomeEvent(new Foo());
}

鉴于上述情况,我需要做什么?我100%可以改为动作列表或其他东西,但似乎我应该能够停止后续事件的执行。

注意:显示的代码只是为了复制问题,而不是我的程序结构。实际程序正在处理传入的网络事件,并且有一个在其上运行的任意委托列表。我不想在一个问题上发布这一切。

......也许我只是试图以一种他们不打算使用它们的方式使用它们,我对此很好,我只是希望我只需要学习一些新东西关于C#中的事件。

感谢您的时间!

2 个答案:

答案 0 :(得分:2)

你可以使用像HandledEventArgs这样的东西(或使用类似的概念),这样,当处理事件时,你设置'处理'属性并在你的其他代表中检查这个属性。

不确定是否可以强制它取消所有其他调用,如果稍后再进行调试可能会有点麻烦。

答案 1 :(得分:1)

我想我可能已回答了我自己的问题。

我最终做的是让我的委托返回一个布尔值,然后当我去执行我的事件时,我实际上使用GetInvocationList()来获取委托并调用它们,检查返回值...

新代码如下:

//nonsense class
public class Foo {
    public string Bar { get; set; }
}

//nonsense event.
public event Func<Foo, bool> SomeEvent;

void BindAndFire() {
    //wire it up.
    SomeEvent += (foo) => { 
        var a = DateTime.Now.Millisecond % 2;
        foo.Bar = (a == 0) ? "Hooray" : "Boo";
        return true;
    };
    SomeEvent += (foo) => { 
        return foo.Bar != "Boo";
    };
    SomeEvent += (foo) => { 
        foo.Bar += ", you made it!";
        return true;
    };

    //fire the event.
    var f = new Foo();
    foreach(var s in SomeEvent.GetInvocationList()) {
        if(!s.DynamicInvoke(f)) break;
    }
}

编辑:我最终结合使用了我的答案和上面的蓝莓,因为它更适合我的工作。所以在我的情况下,其中一个事件参数有一个Close()方法,开发人员可以在他的委托内部调用,所以在那里,我设置了一个属性,然后在循环通过GetInvocationList()时检查和中断。

//nonsense class
public class Foo {
    public string Bar { get; set; }
    public bool IsClosed { get; private set; }
    public void Close() {
        IsClosed = true;
    }
}

//nonsense event.
public event Action<Foo> SomeEvent;

void BindAndFire() {
    //wire it up.
    SomeEvent += (foo) => { 
        var a = DateTime.Now.Millisecond % 2;
        foo.Bar = (a == 0) ? "Hooray" : "Boo";
    };
    SomeEvent += (foo) => { 
        if(foo.Bar != "Boo") {
           foo.Close();
        }
    };
    SomeEvent += (foo) => { 
        foo.Bar += ", you made it!";
    };

    //fire the event.
    var f = new Foo();
    foreach(var s in SomeEvent.GetInvocationList()) {
        s.DynamicInvoke(f);
        if(f.IsClosed) break;
    }
}