Как метод ожидает завершения анонимного делегата? - PullRequest
0 голосов
/ 12 февраля 2011

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

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
}

Обновление:
Вот контакт-менеджер:

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 ]

5 голосов
/ 12 февраля 2011

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

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

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

1 голос
/ 12 февраля 2011

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

...