Влияние использования & RemoveHandler в сочетании с асинхронным вызовом ASMX

Учитывая следующий код

    Public Shared Sub DoAsyncAction()
        Using asmxProxy As New MyAsmxServiceProxy()
            AddHandler asmxProxy.WebFunctionCompleted, AddressOf WebFunctionAsync_Completed

            // Make the Async ASMX Webservice Call
            asmxProxy.WebFunctionAsync()

            // RemoveHandler asmxProxy.WebFunctionCompleted, AddressOf WebFunctionAsync_Completed
        End Using
    End Sub

    Private Shared Sub WebFunctionAsync_Completed(ByVal sender As Object, ByVal e As MyAsmxServiceProxy.WebFunctionCompletedEventArgs)
        // Do Stuff
    End Sub

Мне было интересно, как здесь поддерживается обработчик событий. Итак, допустим, WebFunctionAsync() внутренне занимает ~ 30 секунд. Когда это время истечет, будет запущено событие WebFunctionCompleted, но будет ли мой обработчик (WebFunctionAsync_Completed) по-прежнему срабатывать, даже если webClient был удален и вышел из области действия?

Если вопрос к последнему ответу Да, что, если я прокомментировал строку RemoveHandler. Будет ли это тогда?

Я думаю, что я пытаюсь выяснить, во время вызова асинхронной функции зарегистрированные обработчики событий «кэшируются» (так сказать) вместе с вызовом, так что независимо от того, что происходит с прокси-объектом ASMX или даже если обработчики удалены, зарегистрированные обработчики событий во время вызова все равно будут срабатывать при срабатывании событий?

Может быть, это действительно очевидно, но по какой-то причине я не могу прийти к логическому выводу по этому поводу, и я не нашел ответов в тех нескольких местах, которые я искал в MSDN.


person ckittel    schedule 03.02.2010    source источник
comment
Похоже, что этот [1] пост SO может ответить на первый вопрос, но, похоже, не говорит о явном удалении обработчика. [1] stackoverflow.com/questions/421547/   -  person ckittel    schedule 03.02.2010


Ответы (2)


ИМХО, дело не только в Removehandler'е. В этом случае не следует использовать блок Using. Прокси-сервер передается вам как параметр sender обработчика событий Completed и не должен удаляться, когда он туда попадает.

person John Saunders    schedule 03.02.2010
comment
Интересная мысль. На самом деле у меня не было намеренного желания ссылаться на отправителя в обработчике, поэтому я никогда не учитывал этот факт. Я предполагаю, что читая здесь между строк, вы говорите, что даже если asmxProxy удален, обработчик событий все равно будет вызываться в этом случае - отвечая на первый вопрос, который у меня был. Правильно? - person ckittel; 03.02.2010
comment
Должен ли тогда обработчик событий SendHtmlEMailCompleted нести ответственность за .Dispose() отправителя (и, возможно, даже перед первым RemoveHandler)? - person ckittel; 03.02.2010
comment
@ckittel: да. Даже если вы явно не используете экземпляр прокси в обработчике, учтите, что он, скорее всего, будет использоваться непосредственно перед вызовом обработчика - для отправки в обработчик! - person John Saunders; 03.02.2010

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

... но будет ли мой обработчик (WebFunctionAsync_Completed) по-прежнему получать удары, даже если веб-клиент был удален и вышел за рамки?

С кодом, представленным выше, Да будет вызван обработчик, но, как указал @JohnSaunders, параметр sender обработчика событий будет удаленным экземпляром MyAsmxServiceProxy объект. Вероятно, это не имеет большого значения, если вы не планируете использовать его в обработчике, я полагаю, но все же стоит отметить.

Если вопрос к последнему ответу Да, что, если я прокомментировал строку RemoveHandler. Будет ли это тогда?

С закомментированной строкой RemoveHandler возникает состояние гонки. Если строка RemoveHandler вызывается до запуска события Completed, обработчик никогда не вызывается. Итак, ответ на второй вопрос — Нет.

person ckittel    schedule 03.02.2010