【问题标题】:How does a method wait until an anonymous delegate completes?方法如何等待匿名委托完成?
【发布时间】:2011-02-12 11:02:20
【问题描述】:

我有以下 sn-p 代码(作为示例)查找联系人:

public string Search()
{
    string address = "";

    ContactManager manager = new ContactManager();

    // LookupComplete is just a plain event
    manager.LookupComplete += delegate
    {
        address = manager.Address;
    };

    manager.SearchFor("bob");
    return address; // Address always appears to be populated
}

更新:
这是 ContactManager:

public class ContactManager
{
    public string Address {get;set;}
    public event LookupComplete;

    public void SearchFor(string query)
    {
        SomeParser parser = new Parser();
        parser.TokenParsed += new EventHandler<TokenParseEventArgs>(tokenParsed);
        parser.Parse(query);    
    }

    private void tokenParsed(object sender,TokenParseEventArgs e)
    {
        if (e.Message == "EOF")
        {
            Address = e.Message.Address;

            if (LookupComplete != null)
                LookupComplete(this,EventArgs.Empty);
        }   
    }   
}

Search 方法在触发该事件之前不会返回(我没有意识到这是匿名方法/委托的标准行为)。

但是,我很困惑为匿名委托生成的代码如何在完成时向Search 方法发出信号。

我已经尝试在 ContactManager.Address 属性中放置一个 Sleep(5000),因为我认为它可能来自 ContactManager 只是很快返回,但这没有什么区别。

谁能解释一下?

【问题讨论】:

    标签: c# events anonymous-methods anonymous-delegates


    【解决方案1】:

    这与委托是否使用匿名方法创建无关。只是manager.SearchFor 显然是一个同步方法,直到查找完成才返回。诚然,这使得它有一个“查找完成”事件有点奇怪......看起来你可以将你的方法简化为:

    public string Search()
    {
        ContactManager manager = new ContactManager();
        manager.SearchFor("bob");
        return manager.Address;
    }
    

    现在ContactManager 上可能提供了一个异步选项 - 如果不了解该类的更多信息,很难说。如果一个异步选项,你应该考虑你真正想要的行为......你对Search同步感到满意,还是你真的希望它立即完成并在搜索完成了吗?

    【讨论】:

    • 我试图用联系人来简化它,'ContactManager' 实际上是这样的:hg.shrinkrays.net/spruce/src/0e9aee07563e/Spruce.Core/Search/…。它在查询中解析令牌,但据我所知并没有同步运行
    • @Chris S:我在该代码中看不到任何暗示它是异步的...但我看不到 LALRParser 的代码。是否有一些文档向您表明它真的是异步的?
    • @Chris S 我在那里没有找到任何异步调用
    • @Jon 和 @gor SearchFor 完成,TokenParsed 事件稍后触发,除非我错过了什么?
    • @Chris S:但是是什么让你这么想呢?您是否有任何证据表明 SearchFor 在引发 TokenParsed 事件之前 完成?
    【解决方案2】:

    这取决于ContactManager 类的实现。如果它是单线程和同步的,它不能提前返回,那么工作就完成了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      • 1970-01-01
      相关资源
      最近更新 更多