Как метод ожидает завершения анонимного делегата?

У меня есть следующий фрагмент кода (в качестве примера), который ищет контакт:

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 метод, когда он завершен.

Я попытался поместить Sleep(5000) в свойство ContactManager.Address, поскольку я думал, что это может быть из ContactManager, который просто очень быстро возвращается, но это не имеет значения.

Кто-нибудь может пролить свет?

2 ответа

Решение

Это не имеет ничего общего с тем, был ли делегат создан анонимным методом. Это просто manager.SearchFor по-видимому, синхронный метод, который не возвращается, пока поиск не завершится. Это немного странно для него иметь событие для "завершения поиска", по общему признанию... похоже, что вы могли бы упростить свой метод до простого:

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

Теперь возможно, что есть также асинхронная опция, доступная на ContactManager - трудно сказать, не зная больше о классе. Если есть асинхронный вариант, вы должны рассмотреть, какое поведение вы на самом деле хотите... вы довольны Search быть синхронным, или вы действительно хотите, чтобы он завершился немедленно и предпринял некоторые действия после завершения поиска?

Это зависит от реализации ContactManager учебный класс. Если он однопоточный и синхронный, он не может вернуться раньше, тогда работа выполнена.

Другие вопросы по тегам