解决从 Silverlight 同时调用 WCF 服务上的多个方法时的阻塞问题
我刚刚阅读了这篇关于从 Silverlight 同时调用 WCF 服务上的多个方法的有趣文章:
文章指出:“事实证明,该问题是由 Silverlight、Asp.Net 和 WCF 混合产生的,基本上如果您“正在对单个 WCF Web 服务进行多次调用,并且启用了 Asp.Net 会话状态,这些调用将由服务按顺序执行,因此任何长时间运行的调用都将阻止后续调用。”
我假设只有当您对同一个服务进行多次调用时,阻塞才是一个问题,并且对两个不同服务上的两个不同方法的两次同时调用不应导致一个挡住对方?
针对 SL3 中问题的建议解决方案涉及在 Application_Startup 方法中使用以下语法:
WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
然后必须维护会话状态通过设置 cookie 容器并在所有代理之间共享它来进行 WCF 调用(请参阅 http://forums.silverlight.net/forums/p/174322/393032.aspx)
这仍然是 Silverlight 4 中推荐的解决方案吗?有人使用过替代方法吗?
I've just read this interesting article regarding simultaneously calling multiple methods on a WCF service from Silverlight:
The article states: "It turns out that the issue is founded in a mix of Silverlight, Asp.Net and WCF, basically if you’re doing multiple calls to a single WCF web-service and you have Asp.Net session state enabled, the calls will be executed sequentially by the service, hence any long running calls will block subsequent ones."
I am assuming that the blocking is only an issue if you are making multiple calls to the same service, and that two simultaneous calls to two different methods on two different services should not result in one blocking the other?
The suggested solution to the problem in SL3 involves using the following syntax in the Application_Startup method:
WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
The session state will then have to be maintained on WCF calls by seting up a cookie container, and sharing it across all of your proxies (see http://forums.silverlight.net/forums/p/174322/393032.aspx)
Is this still the recommended solution in Silverlight 4? Has anyone used an alternative approach?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 .NET 4 中,您可以在
Application_BeginRequest
中执行此操作In .NET 4, you can do this in
Application_BeginRequest
如果您正在调用 ASP.Net 应用程序,并且正在使用会话 cookie,则所有对应用程序的调用都会被序列化(页面明确选择退出会话状态的调用除外) 。
通常这不是一个大问题,因为客户端浏览器通常会访问 ASP.Net 页面以及一堆资源(图像、js、css 等...),而后者不会映射到 ASP。 Net,因此 IIS 本身就可以为它们提供服务。但是,如果您尝试同时点击两个 ASP.Net 页面(例如在框架集中),您将看到它们相继加载。
现在我不知道 WCF 是否会发生这种情况,但根据您的说法,如果您看到一项服务的这种行为,我希望看到所有服务的这种行为,因为会话是针对每个服务的- 用户,而不是每个服务。
在 ASP.Net 中,您可以逐页“选择退出”会话状态。如果这对于托管 WCF 服务来说是可能的,并且对于您的方案可行(使服务无状态),那么问题就会得到缓解。或者将一项或多项服务移动到不同的 ASP.Net 应用程序(不同的会话)。
请记住,您可以在此处看到与服务的实例化和重入模型有关的其他问题。如上所述,您的问题是每个用户的并发问题,但还有其他问题。例如,如果您将服务设置为单例 (InstanceContextMode.Single) 和不可重入 (ConcurrencyMode.Single),则所有用户一次只会处理一个请求。
更新:做一些 doco 阅读:
Wenlong Dong's site
因此,从我看来,您应该能够使用 AspNetCompatibilityRequirementsMode.NotAllowed 从 ASP.Net 服务中完全选择退出个别服务。或者,默认情况下将其保留,仅选择需要访问 ASP.Net 会话的会话(请记住,除非您确实需要与 ASP.Net 共享同一会话,否则仅使用 WCF 的会话服务可能是一个不错的选择)更好的选择)。
If you are making a call into an ASP.Net application, and you are using session cookies, then all the calls into the application are serialized (apart from ones where the page explicitly opts out of session state).
Normally this isn't a big issue, because a client browser typically hits an ASP.Net page plus a bunch of resources (images, js, css etc...), and these latter aren't mapped to ASP.Net so IIS serves them up natively. But if you try and hit two ASP.Net pages at the same time (eg in a frameset) you will see them load up one after another.
Now I don't know that this happens with WCF, but based on what you say, if you see that behaviour for one service I would expect to see that for all of them, because the session is per-user, not per-service.
In ASP.Net you can 'opt out' of session state on a page by page basis. If that's possible for a hosted WCF service, and viable for your scenario (to make the services stateless) that would aleviate the issue. Or move one or more services to a different ASP.Net application (different session)
Bear in mind that you can see other issues here to do with the instancing and reentrancy models of the service. Your problem as described above is a per-user concurrency issue, but there are others. For example, if you set the service up as a singleton (InstanceContextMode.Single) and non-reentrant (ConcurrencyMode.Single) then only one request will ever be processed at a time across all users.
Update: Doing some doco reading:
There's a good blog post about this on Wenlong Dong's site
So from what I can see you should be able to use AspNetCompatibilityRequirementsMode.NotAllowed to opt out individual services completely from ASP.Net services. Alternatively, leave it off by default and only opt-in the ones that need access to the ASP.Net session (bearing in mind that unless you really need to share the same session with ASP.Net, just using WCF's session services is probably a better bet).