обратные вызовы в C #, порядок вызова и возврата - PullRequest
6 голосов
/ 12 мая 2011

Простой вопрос по обратным вызовам.Возвращаются ли функции обратного вызова на следующую строку в вызывающей функции после завершения?

class A
{
 public delegate void A();
 public event A onA;

 public void func()
 {
   //some code 1
  onA();
  //some code 2 
 }

Таким образом, вопрос заключается в том, будет ли событие onA идти и выполнять соответствующий обработчик, а затем возвращаться к биту «некоторого кода 2» илиэтот асинхронный код не будет ждать полной обработки события?

Надеюсь, вопрос ясен.

Спасибо}

Ответы [ 5 ]

3 голосов
/ 12 мая 2011

То, как вы использовали делегат: синхронно. Если вы хотите асинхронный, вы должны вызвать делегат с помощью метода: BeginInvoke.

2 голосов
/ 12 мая 2011

Ваш код не является асинхронным.Но вы можете использовать делегатов асинхронно .

2 голосов
/ 12 мая 2011

Да, в вашем примере onA () будет запускать все обработчики событий, подключенные к A, чтобы срабатывать.Это просто методы, которые будут вызываться.После того, как они все вызваны, управление вернется к функции ().

Это не асинхронный - вы используете только один поток.Все будет происходить в четко определенном порядке.

Хороший способ экспериментировать - пройтись по коду в вашем примере, используя встроенный отладчик.

1 голос
/ 12 мая 2011

Нет, вызов события не является асинхронным.Ваш код func() продолжится только после окончания работы onA().

Вы бы использовали BeginInvoke или Threading, если захотите, чтобы выполнялся ассинк-код.

Подробнее о вызовах делегатов здесь .

0 голосов
/ 12 мая 2011

Как уже отмечали другие, это полностью синхронно.Если вы хотите выполнить это асинхронно, вам придется написать это по-другому.

Кроме того, если на событие 'onA' не подписано, onA () вызовет исключение нулевой ссылки.

Обычным шаблоном является определение события «Foo» и метода «OnFoo», который вызывается при возникновении события.Из названия события я подозреваю, что это то, что вы хотите - например: -

class Foo // Class and member names must be distinct
{
    public delegate void ADelegate();
    public event ADelegate A;

    private void OnA()
    {
        if(A != null)
            A();
    }

    public void Func()
    {
        // Some code...
        OnA();
        // More code...
    }
}

Если вы хотите вызывать подписанные обработчики событий асинхронно, вы можете использовать BeginInvoke () и EndInvoke () таким образом: -

class Foo // Class and member names must be distinct
{
    public delegate void ADelegate();
    public event ADelegate A;

    private void OnA()
    {
        if (A == null) return;

        // There may be multiple subscribers, invoke each separately.
        foreach(ADelegate del in A.GetInvocationList())
            del.BeginInvoke(SubscriberCallback, del);
    }

    private void SubscriberCallback(IAsyncResult result)
    {
        var del = (ADelegate) result.AsyncState;
        del.EndInvoke(result);
        // Do something in the callback...
    }

    public void Func()
    {
        // Some code...
        OnA();
        // More code...
    }
}

Обратите внимание, что этот код не будет ждать окончания выполнения подписчика (ей) события, вам нужно будет пропустить асинхронный результат через вызов события, чтобы убедиться в этом.

Обратите внимание, что callback - это метод, который вы указываете в асинхронном BeginInvoke (так как он вызывается обратно после выполнения асинхронной работы) и не возвращается к Func (), поскольку выполняется вотдельная тема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...