Не используйте односторонний, если вам нужны результаты
Во-первых, если вам нужен ответ от вашего метода, вы не хотите, чтобы [SoapDocumentMethod(OneWay = true)]
. Этот атрибут создает вызов «огонь и забвение», который никогда не возвращает ответ обратно на катер и должен возвращать void
. Вместо этого используйте обычный вызов метода и назовите его async.
Один или два метода?
Если вы используете ASMX, существует два основных решения: один метод с очень длинным таймаутом или два метода (как @Aaronaught suggested above): один для запуска операции и возврата идентификатора операции, а другой - передать идентификатор и получить результаты (если они доступны).
Лично я бы не рекомендовал это два-метода подход в большинстве случаев из-за дополнительной сложности участие, в том числе:
- клиента и код сервера должен быть изменен на Suppport 2-ступенчатый Призыва
- Внутренними объектами ASP.NET, такими как
Request
и Response
являются not available when called from a background task launched with ThreadPool.QueueUserWorkItem
.
- Дросселирование на занятом сервере становится намного сложнее, если с каждым запросом задействовано несколько потоков.
- сервер должен висеть на результатах до тех пор, пока клиент не подберет их (или вы не выберете их), которые могут съесть RAM, если результаты будут большими.
- вы не можете передавать большие, промежуточные результаты обратно клиенту
Правда, в некоторых сценариях 2-метод подход может масштабироваться лучше и будет более устойчивым к сломанной сетевые соединения между клиентом и сервером. Если вам нужно забрать результаты за несколько часов позже, это нужно рассмотреть. Но ваши операции занимают всего несколько минут, и вы можете гарантировать, что клиент будет оставаться подключенным, учитывая сложность адъютационной функции 2-метода, я бы счел, что это последнее средство, которое будет использоваться, только если решение с одним методом не будет соответствуют вашим потребностям.
В любом случае, решение требует двух частей. Во-первых, вам нужно вызвать метод асинхронно с клиента. Во-вторых, вам нужно удлинить таймауты как на клиенте, так и на сервере. Я охватываю оба ниже.
Вызов ASMX Web Services Асинхронный
Для вызова веб-службы ASMX асинхронно из приложения командной строки, посмотрите на this article начиная с страницы 2. Он показывает, как вызвать веб-сервис асинхронно из Приложение .NET cilent, используя новый Event-Based Async Pattern. Обратите внимание, что старший .NET 1.0, описанный here, который полагается на методы BeginXXX/EndXXX на прокси, больше не рекомендуется больше, так как генератор прокси-сервера Visual Studio не создает эти методы. Лучше использовать шаблон, основанный на событиях, как указано выше.
Вот выдержка/адаптация из приведенных выше статей, так что вы можете получить представление о коде вовлеченной:
void KickOffAsyncWebServiceCall(object sender, EventArgs e)
{
HelloService service = new HelloService();
//Hookup async event handler
service.HelloWorldCompleted += new
HelloWorldCompletedEventHandler(this.HelloWorldCompleted);
service.HelloWorldAsync();
}
void HelloWorldCompleted(object sender,
HelloWorldCompletedEventArgs args)
{
//Display the return value
Console.WriteLine (args.Result);
}
удлиняет сервер и клиент таймауты
Чтобы предотвратить таймаут, http://www.dotnetmonster.com/Uwe/Forum.aspx/asp-net-web-services/5202/Web-Method-TimeOut имеет хорошая сводка о том, как настроить как таймауты клиента, так и сервера. Вы не указали в своем вопросе, если у вас есть метод на стороне сервера или только на стороне клиента вызов, поэтому ниже отрывок охватывает оба случая:
там есть два setttings, которые влияют на тайм-аут вебсервис вызова поведение:
** настройка на стороне сервера httpruntime Тайм-аут The WebService ASP.NET, это настраивается через следующий элемент:
httpRuntime элемент (схема параметров ASP.NET)
http://msdn2.microsoft.com/en-us/library/e1f13641.aspx
< Конфигурация> < system.web>
< httpRuntime .............
ExecutionTimeout = "45"
........... .... /> < /system.web> </конфигурация>
Кроме того, убедитесь, что вы установили < компиляции отлаживать = "ложных" /> так, чтобы сделать работу таймаута правильно ,
** Если вы используете wsdl.exe или VS IDE «добавить webreference» сгенерированный прокси для вызова методов веб-сервиса, есть также тайм-аут настройки на прокси-класса клиента (производный от класса SoapHttpClientProtocol) , Это свойство «Тайм-аут» происходит от «WebClientProtocol» класса:
WebClientProtocol.Timeout собственности http://msdn2.microsoft.com/en-us/library/system.web.services.protocols.webclientprotocol.timeout.aspx
Таким образом, вы можете рассмотреть вопрос о корректировке эти два значения в соответствии со сценарием вашего приложения. Вот это бывший нить также упомянул об этом:
http://groups.google.com/group/microsoft.public.dotnet.framework.webservices/browse_thread/thread/73548848d0544bc9/bbf6737586ca3901
Обратите внимание, что я настоятельно рекомендую сделать ваши таймауты достаточно долго, чтобы охватить вашу самую длинную операцию (плюс достаточное количество буфера, чтобы быть в безопасности, должны получить все медленнее) но я бы не рекомендовал полностью отключать таймауты. Как правило, плохая практика программирования позволяет неограниченное время ожидания, так как ошибочный клиент или сервер может навсегда отключить другой. Вместо этого достаточно просто сделать тайм-ауты - и убедитесь, что вы регистрируете экземпляры, где ваши клиенты или серверы тайм-аут, поэтому вы можете обнаружить и диагностировать проблему, когда это произойдет!
Наконец, чтобы повторить комментарии выше: для нового кода лучше всего использовать WCF. Но если вы застряли с использованием веб-служб ASMX, это решение должно работать.
Вам нужен ответ с вашего веб-метода? – lajuette
Использование веб-служб ASMX не является «хорошим способом», если вы не застряли с использованием .NET 2.0. Microsoft теперь рассматривает веб-службы ASMX как «устаревшую технологию». Все новые разработки веб-сервисов должны быть выполнены с использованием WCF. –
Статья в MSDN с меткой примечания о том, что ASMX является «устаревшим» (в то время как более новые статьи в MSDN об ASMX do * not * несут эту заметку) не делает ASMX еще хуже, чем он делает. В лучшем случае вся эта дискуссия ортогональна вопросу Фенево. –