C#在调用后删除事件处理程序或只调用一次

时间:2013-12-21 09:47:02

标签: c# events

_cefGlueBrowser.LoadEnd += (s, e) =>
{
    BeginInvoke(new Action(() =>
    {
         MyCefStringVisitor visitor = new MyCefStringVisitor(this, m_url);
         e.Browser.GetMainFrame().GetSource(visitor);
         loaded = true;
    }));
};

但问题是Event Handler被多次调用。在每次JS重新加载之后。如何删除多个电话。如何只调用一次LoadEnd事件。

我尝试

_cefGlueBrowser.LoadEnd -= delegate { };

但没有工作。

我该怎么办?我只想打电话一次!

4 个答案:

答案 0 :(得分:27)

EventHandler handler = null;
obj.SomeEvent += handler = (s, e) => {
    obj.SomeEvent -= handler;
    // more stuff
};

这是有效的,因为它是我们捕获的变量(词法闭包),而不是任何特定时间变量的值。

答案 1 :(得分:3)

创建方法

public void Browser_LoadEnd(object sender, EventArgs e)
{
    BeginInvoke(new Action(() =>
    {
         MyCefStringVisitor visitor = new MyCefStringVisitor(this, m_url);
         _cefGlueBrowser.Browser.GetMainFrame().GetSource(visitor);
         loaded = true;
    }));
}

订阅

_cefGlueBrowser.LoadEnd += Browser_LoadEnd;

并取消订阅

_cefGlueBrowser.LoadEnd -= Browser_LoadEnd;

注意,我假设LoadEnd事件需要EventArgs而不是某些派生类。

答案 2 :(得分:2)

在单独的方法中定义事件处理程序,并将取消订阅操作添加到其方法体:

public EventHandler OnLoadEnd(object sender, <args>)
{
    BeginInvoke(new Action(() =>
                    {
                        MyCefStringVisitor visitor = new MyCefStringVisitor(this, m_url);
                        _cefGlueBrowser.Browser.GetMainFrame().GetSource(visitor);
                        loaded = true;
                    }));

    _cefGlueBrowser.LoadEnd -= OnLoadEnd;
}

答案 3 :(得分:1)

根据Mark Gravel的反应,我认为你至少还需要一个旗帜

        bool done = false;
        EventHandler eh = null;
        obj.evt += eh = (_, e) => {
            obj.evt -= eh;
            if (done)
                return;
            done = true;

            // stuff
        };