3

我目前正在使用一个事件来触发一组委托,并且我需要能够防止剩余的委托从另一个委托中触发。

以下代码复制了该场景...

//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#。

感谢您的时间!

4

2 回答 2

2

您可以使用 HandledEventArgs 之类的东西(或使用类似的概念),这样,在处理事件时,您可以设置“已处理”属性并在其他委托中检查此属性。

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

于 2012-06-25T00:49:47.163 回答
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;
    }
}
于 2012-06-25T00:46:07.320 回答