How does a method wait until an anonymous delegate completes?

779 views Asked by At

I have the following snippet of code (as an example) that looks up a contact:

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
}

Update:
Here's the 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);
        }   
    }   
}

The Search method doesn't return until that event is fired (a behaviour I didn't realise was standard for anonymous methods/delegates).

I'm confused however how the code generated for the anonymous delegate signals the Search method when it's complete.

I've tried putting a Sleep(5000) in the ContactManager.Address property as I thought it may have been from the ContactManager simply returning very quickly, but that makes no difference.

Can anyone shed any light?

2

There are 2 answers

7
Jon Skeet On BEST ANSWER

This has nothing to do with whether the delegate was created with an anonymous method. It's just that manager.SearchFor is apparently a synchronous method, which doesn't return until the lookup has finished. That makes it slightly strange for it to have an event for "lookup complete", admittedly... it looks like you could simplify your method to simply:

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

Now it's possible that there's also an asynchronous option available on ContactManager - it's hard to say without knowing more about the class. If there is an asynchronous option, you should consider what behaviour you actually want... are you happy with Search being synchronous, or do you actually want it to complete immediately and take some action when the search has finished?

0
gor On

It depends on implementation of ContactManager class. If it is sinle threaded and synchronous it cannot return earlier, then work is done.