Создание метода веб-сервиса асинхронным в C # / Winforms - PullRequest
1 голос
/ 24 июня 2009

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

Каков наилучший способ создания асинхронной оболочки для такого метода в C # / winforms?

В данный момент я использую ThreadPool для запуска метода веб-сервиса, а затем вызываю событие, когда веб-сервис завершается. Как то так.

DoWorkAsync() {
    Webservice.LongMethod()
    WorkCompleteEvent()
}

Однако это не кажется идеальным. Например, если я пытаюсь изменить элементы управления формы из обработчика событий, я получаю предупреждение о том, что это не делается из другого потока и т. Д.

У кого-нибудь есть еще предложения по решению этой проблемы?

Ответы [ 3 ]

6 голосов
/ 24 июня 2009

См. Статью MSDN по Как: выполнять потокобезопасные вызовы для элементов управления Windows Forms , а также замечательное руководство Джона Скита по созданию потоков , более конкретно Потоки в Windows Forms .

Цитирую Джона (выделено мое):

Никогда не вызывайте какие-либо методы или свойства для элемента управления, созданного в другом потоке, кроме Invoke , BeginInvoke , EndInvoke или CreateGraphics , и InvokeRequired . Каждый элемент управления эффективно связан с потоком, который запускает свой насос сообщений. Если вы пытаетесь получить доступ или изменить что-либо в пользовательском интерфейсе (например, изменить свойство Text) из другого потока, вы рискуете зависания или неправильного поведения вашей программы другими способами. Вам это может сойти с рук. в некоторых случаях, но только по счастливой случайности. К счастью, были предоставлены методы Invoke, BeginInvoke и EndInvoke, так что вы можете попросить поток пользовательского интерфейса вызвать метод для вас безопасным способом.

1 голос
/ 24 июня 2009

Решение заключается в использовании встроенного асинхронного решения для веб-сервисов. Используйте webservice.BeginLongMethod () для вызова и использования IAsyncResult. Но помните, что вы всегда должны использовать методы Invoke для обновления кода форм Windows, поскольку он находится в другом потоке.

см. Следующие статьи

http://www.informit.com/articles/article.aspx?p=29395&seqNum=4

http://msdn.microsoft.com/en-us/library/ms228972.aspx

0 голосов
/ 24 июня 2009

Вы можете использовать асинхронные делегаты для вызова веб-метода. Вы можете взглянуть на Асинхронное копирование / перемещение файла в C # , чтобы увидеть, как это можно сделать. Представьте, что FileCopy - это ваш веб-метод (а не метод класса, как показано в примере.)

Для ошибок между потоками вы можете обратиться к Ошибка операций перекрестных потоков

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