如何定义异步 ASP.NET Web 服务调用的客户端超时?
今天,我搜索了一些特定的案例,用于调用(外部)ASP.NET Web 服务,并满足以下要求:
- 调用必须异步完成
- 必须实现超时,因为 Web 服务可能需要很长时间才能
执行互联网和 StackOverflow 上出现了许多关于此主题的问题,但要么已过时,要么建议使用仅适用于同步调用的 WebRequest.TimeOut
属性。
一种替代方法是使用 System.Threading.Timer。在开始调用之前启动计时器,并在到达 TimerCallback
时取消计时器。
然而,我认为应该有一个更通用的方法来处理此类情况。不幸的是到目前为止还没有找到它。有人知道如何在异步 Web 服务调用上设置客户端超时吗?
提前致谢。
Today I've searched some time to a specific case we have for calling an (external) ASP.NET web service with the following requirements:
- Calls must be done asynchronous
- A timeout must implemented, because web service can take long time to execute
On the internet and StackOverflow many questions appear on this subject, but are either dated or are suggesting using the WebRequest.TimeOut
property which is only applicable for synchronous calls.
One alternative is using an System.Threading.Timer
. Starting the timer just before starting the call and cancelling it when it reaches the TimerCallback
.
However, I think there should be a more common approach to such cases. Unfortunately couldn't find it so far. Anyone has an idea for setting client side timeouts on async web service calls?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
请检查您的 app.config,它会有一些 servicemodel 设置,并且有各种可以配置的值。
当我添加新的服务引用时,我可以在 app.config 中看到以下内容,
尝试再次删除并添加引用,确保您的应用程序的目标框架是 4.0 并且您正在添加服务引用(不是 Web 引用)。
Please check your app.config it will have some settings for servicemodel and it has various values that can be configured.
When I added new Service Reference, I can see following things in my app.config,
Try removing and adding reference again, make sure your app's target framework is 4.0 and you are adding Service Reference (Not the Web Reference).
事实上,您不能总是使用 WebRequest.TimeOut 来进行异步操作;至少对于抽象
WebRequest
类的所有实现者来说不是这样。例如,msdn 上记录了此属性 时被忽略调用HttpWebRequest.BeginGetResponse
启动异步操作。明确指出TimeOut
属性将被忽略,并且用户有责任在需要时实现超时行为。在
HttpWebRequest.BeginGetResponse
附带的示例代码中 msdn 文档中,ManualResestEvent allDone
与WaitOrTimerCallback
结合使用,如下所示:请参阅 msdn 上的完整示例。
最重要的是你必须自己实现这一点。
Indeed you cannot always use
WebRequest.TimeOut
for async operations; at least not for all implementers of the abstractWebRequest
class. For instance it is documented on msdn that this property is ignored when callingHttpWebRequest.BeginGetResponse
to start an async operation. It is explicitly stated that theTimeOut
property is ignored and that it's the user's responsibility to implement timeout behavior if required.In the example code coming with the
HttpWebRequest.BeginGetResponse
documentation on msdn, aManualResestEvent allDone
in combination with aWaitOrTimerCallback
is used as follows:Please see the complete example on msdn.
The bottom line is you have to implement this yourself.
我做了一个小项目来演示如何做到这一点;事情并不像我想象的那么简单,但是,到底是什么?
这是带有 Web 服务的整个项目,还有 WPF 中的客户端,其中有一个用于调用带超时和不带超时的按钮 http://www.mediafire.com/file/3xj4o16hgzm139a/ASPWebserviceAsyncTimeouts.zip。我将在下面放置一些相关的片段。我使用 DispatcherTimer 类(如代码中所述)进行超时;看起来这个对象显然是 WPF 友好的,并且(应该)缓解大多数(如果不是全部)否则可能会遇到的同步问题。
注意:它可能可以通过 WCF 风格的“服务引用”以某种方式完成,但是,我无法找出方法并遇到了很多死胡同。我最终选择了旧样式的“Web 引用”(您可以通过转到“添加服务引用...”,选择“高级”按钮,然后选择“添加 Web 引用”来访问它。
我的原因是与帮助程序类一起使用的目的是演示在有很多调用的情况下可以做什么;如果我们没有它,那么跟踪所有内容很快就会变得混乱,可能会得到一个更通用的版本。几乎所有的处理都可以在代码中完成,但是 WCF由于服务参考代码中使用泛型的方式,花费了我大部分时间的代码并不适合这种处理,我只是快速查看了 Web 服务代码,而且看起来更有可能做到这一点。 ,但不幸的是,我没有足够的时间来研究这部分内容,请告诉我,我会看看我
现在可以做些什么!
进行回调的助手:
AsyncCallHelper.cs
MainWindow.xaml.cs
文件包含相关代码:i worked up a little project that demonstrates how to do this; it was not as simple as i figured it would be, but, then, what ever is?
here's the whole project with a webservice and also a client in WPF that has a buttons for calling both with and without timeout http://www.mediafire.com/file/3xj4o16hgzm139a/ASPWebserviceAsyncTimeouts.zip. i'll put some relevant snippets below. i used the DispatcherTimer class as described in the code for doing the timeouts; it looks like this object is apparently WPF friendly and (should) relieve most if not all of the synchronization issues that could otherwise be encountered.
NOTE: it probably can be done, somehow, with WCF-style "Service References", however, i was not able to figure out the way and hit a lot of dead ends. i finally ended up going with an older style "Web Reference" (which you can get to by going to "Add Service Reference...", choosing the "Advanced" button, and then choosing "Add Web Reference".
the reason i went with the helper class was to demonstrate what can be done in case you have many calls; keeping track of everything would get messy very quickly if we didn't have that. also, it would probably be possible to get a more generic version where almost all the handling could be done in the code, but the WCF code which took most of my time did not lend itself to that kind of handling due to the way generics are used in the service reference code. i have only quickly looked at the web service code, and it looks more likely that it could be done, but i unfortunately didn't have enough time to play around with that part of things. let me know if you would like me to take a further look and i'll see what i can do.
now on with the show! ;)
helper for doing callback:
AsyncCallHelper.cs
the
MainWindow.xaml.cs
file with the relvant code:我不知道这是否惯用,但在通过
WebClient.DownloadStringAsync(...)
发出异步请求时,我还使用了 Silverlight 中的计时器(DispatchTimer
)。I don't know whether it's idiomatic, but I also use a timer (a
DispatchTimer
) from Silverlight when issuing async requests viaWebClient.DownloadStringAsync(...)
.Web 服务返回什么? XML、JSON 还是其他?您是否将其用于网站之类的用途?如果是这样,为什么不尝试使用 jquery ajax 调用,然后可以异步加载它,并且可以使用 .ajax() 指定超时。
What does the web service return? An XML, JSON, or other? Are you using this for like a web site? If so why don't you try to use jquery ajax call and you can then load it async and you can specify a time out with .ajax().