异步webmethod没有超时

use*_*618 4 c# web-services

我需要一个调用webmethod的控制台应用程序.

它必须是异步的,没有超时(我们不知道这个方法需要花多少时间来处理任务.

这是好方法:

[WebMethod]
[SoapDocumentMethod(OneWay = true)]
Run Code Online (Sandbox Code Playgroud)

??

Jus*_*ant 5

如果您需要结果,请勿单向使用

首先,如果您需要方法的响应,则不需要[SoapDocumentMethod(OneWay = true)].此属性创建一个"即发即弃"调用,该调用永远不会将响应返回给caler并且必须返回void.相反,使用常规方法调用并将其称为异步.

一种方法还是两种?

如果您正在使用ASMX,则有两种基本解决方案:一种具有超长超时的方法,或两种方法(如上面提到的 @Aaronaught ):一种启动操作并返回操作的ID,另一种通过在ID和检索结果(如果可用).

就个人而言,我不建议在大多数情况下使用这种双方法,因为涉及额外的复杂性,包括:

  • 客户端和服务器代码需要更改为支持两步调用
  • ASP.NET内部对象喜欢RequestResponse从启动一个后台任务调用时不可用ThreadPool.QueueUserWorkItem.
  • 如果每个请求涉及多个线程,那么在繁忙的服务器上进行限制会变得更加困难.
  • 服务器必须挂起结果,直到客户端选择它们(或者你决定将它们抛出),如果结果很大,可能会占用RAM.
  • 您不能将大的中间结果流回客户端

确实,在某些情况下,2方法方法可能会更好地扩展,并且对客户端和服务器之间断开的网络连接更具弹性.如果您需要在几小时后获取结果,则需要考虑这一点.但是你的操作只需要几分钟,你可以保证客户端将保持连接,考虑到2方法方法的附加开发复杂性,我认为只有当单方法解决方案不能使用时,它才是最后的选择.符合您的需求.

无论如何,解决方案需要两件.首先,您需要从客户端异步调用该方法.其次,您需要延长客户端和服务器上的超时.我在下面报道.

异步调用ASMX Web服务

要从命令行应用程序异步调用ASMX Web服务,请从第2页开始查看本文.它演示了如何使用较新的基于事件的异步模式从.NET cilent应用程序异步调用Web服务.请注意,由于Visual Studio的代理生成器不创建这些方法,因此不再推荐使用此处描述的较旧的.NET 1.0方法,该方法依赖于代理上的BeginXXX/EndXXX方法.最好使用上面链接的基于事件的模式.

以下是上述文章的摘录/改编,因此您可以了解所涉及的代码:

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);
}
Run Code Online (Sandbox Code Playgroud)

延长服务器和客户端超时

为了防止超时,http://www.dotnetmonster.com/Uwe/Forum.aspx/asp-net-web-services/5202/Web-Method-TimeOut对如何调整客户端和服务器超时进行了很好的总结.您没有在问题中指定您是拥有服务器端方法还是仅拥有客户端调用,因此下面的摘录涵盖了以下两种情况:

有两个设置会影响Web服务调用超时行为:

**ASP.NET webservice的服务器端httpruntime超时设置,通过以下元素配置:

httpRuntime元素(ASP.NET设置架构)
http://msdn2.microsoft.com/en-us/library/e1f13641.aspx

<configuration> <system.web>
<httpRuntime .............
executionTimeout ="45"
............... /> </system.web > </ configuration>

另外,请确保已设置<compilation debug ="false"/>以使超时正常工作.

**如果您使用wsdl.exe或VS IDE"添加webreference"生成的代理来调用Web服务方法,则客户端代理类(从SoapHttpClientProtocol类派生)也会有超时设置.这是从"WebClientProtocol"类派生的"Timeout"属性:

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 Web服务,上述解决方案应该可行.