为什么这些异步 RIA 服务调用在 Web 服务器上串行执行?
我调用 RIA 服务方法 ImportSubcomponentFileSetFiles (这是一个调用,而不是查询)两次,如下所示:
foreach (var viewModel in FileSetViewModels.Where(vm => vm.IsSelectedForImport))
{
DomainContext.ImportSubcomponentFileSetFiles(viewModel.SubcomponentFileSet.Id, callback =>
{
//...
DomainContext.Load(DomainContext.GetSubcomponentFileSetWithStatusQuery(subcomponentFileSetId), LoadBehavior.RefreshCurrent,
callback2 =>
{
//...
}, true);
}, null);
}
我可以在 Fiddler 中看到两个请求立即发送到 ImportSubcomponentFileSetFiles 。
ImportSubcomponentFileSetFiles 大约需要 15 秒才能完成。第一个呼叫约 15 秒后返回,第二个呼叫约 15 秒后返回。我从日志记录中可以看到,直到第一次调用完成后,才会开始对 ImportSubcomponentFileSetFiles 的第二次调用。
我的问题是,为什么这些异步请求在服务器上串行处理以及如何并行处理它们?
其他信息
- WCF Ria 服务托管在 ASP.NET Web 应用程序中。
- 我没有在会话中存储任何内容。
- 我在服务方法中使用实体框架 4。
- Domain Services 类扩展了 LinqToEntitiesDomainService
我的服务方法如下:
public void ImportSubcomponentFileSetFiles(int subcomponentId)
{
Debug.WriteLine("{0}: {1} - ImportSubcomponentFileSetFiles method started", subcomponentId, DateTime.Now);
//...code for fetching subcomponentFileSet
subcomponentFileSet.ImportFiles(ObjectContext);
Debug.WriteLine("{0}: {1} - ImportSubcomponentFileSetFiles method finished", subcomponentId, DateTime.Now);
}
这是我的日志,详细说明了第二个方法调用在第一个方法调用完成之前才开始:
File Set A: 27/1/2011 11:20:06 PM 11:20:06 PM - Calling ImportSubcomponentFileSetFiles (Silverlight Client)
File Set A: 27/1/2011 11:20:06 PM 11:20:06 PM - ImportSubcomponentFileSetFiles Called (Silverlight Client)
File Set B: 27/1/2011 11:20:06 PM 11:20:06 PM - Calling ImportSubcomponentFileSetFiles (Silverlight Client)
File Set B: 27/1/2011 11:20:06 PM 11:20:06 PM - ImportSubcomponentFileSetFiles Called (Silverlight Client)
File Set A: 01/27/2011 23:20:06 - ImportSubcomponentFileSetFiles method started (Server)
File Set A: 01/27/2011 23:20:06 - ImportFiles Started (Server)
File Set A: 01/27/2011 23:20:23 - ImportFiles Finished (Server)
File Set A: 01/27/2011 23:20:23 - ImportSubcomponentFileSetFiles method finished (Server)
File Set A: 27/1/2011 11:20:23 PM - Import callback recieved (Silverlight Client)
File Set A: 01/27/2011 23:20:23 - GetSubcomponentFileSetWithStatus Started (Server)
File Set A: 01/27/2011 23:20:23 - GetSubcomponentFileSetWithStatus Finished (Server)
File Set B: 01/27/2011 23:20:23 - ImportSubcomponentFileSetFiles method started (Server)
File Set B: 01/27/2011 23:20:23 - ImportFiles Started (Server)
File Set A: 27/1/2011 11:20:23 PM - Refresh callback recieved (Silverlight Client)
File Set B: 01/27/2011 23:20:36 - ImportFiles Finished (Server)
File Set B: 01/27/2011 23:20:36 - ImportSubcomponentFileSetFiles method finished (Server)
File Set B: 27/1/2011 11:20:36 PM - Import callback recieved (Silverlight Client)
File Set B: 01/27/2011 23:20:36 - GetSubcomponentFileSetWithStatus Started (Server)
File Set B: 01/27/2011 23:20:36 - GetSubcomponentFileSetWithStatus Finished (Server)
File Set B: 27/1/2011 11:20:36 PM - Refresh callback recieved (Silverlight Client)
干杯,
克里斯
I'm calling the RIA Service method ImportSubcomponentFileSetFiles (which is an Invoke, not Query) twice as follows:
foreach (var viewModel in FileSetViewModels.Where(vm => vm.IsSelectedForImport))
{
DomainContext.ImportSubcomponentFileSetFiles(viewModel.SubcomponentFileSet.Id, callback =>
{
//...
DomainContext.Load(DomainContext.GetSubcomponentFileSetWithStatusQuery(subcomponentFileSetId), LoadBehavior.RefreshCurrent,
callback2 =>
{
//...
}, true);
}, null);
}
I can see in Fiddler that two requests go out to ImportSubcomponentFileSetFiles straight away.
ImportSubcomponentFileSetFiles takes ~15 seconds to complete. The first call comes back after about 15 seconds and the second call comes back 15 seconds after that. I can see from logging that the second call to ImportSubcomponentFileSetFiles doesn't start until the first call has completed.
My question is, why do these asynchronous requests get processed serially on the server and how can I process them in parallel?
ADDITIONAL INFORMATION
- The WCF Ria Services are hosted in an ASP.NET web application.
- I'm not storing anything in the session.
- I'm using Entity Framework 4 in the service method.
- The Domain Services class extends LinqToEntitiesDomainService<MyObjectContext>
My service method is as follows:
public void ImportSubcomponentFileSetFiles(int subcomponentId)
{
Debug.WriteLine("{0}: {1} - ImportSubcomponentFileSetFiles method started", subcomponentId, DateTime.Now);
//...code for fetching subcomponentFileSet
subcomponentFileSet.ImportFiles(ObjectContext);
Debug.WriteLine("{0}: {1} - ImportSubcomponentFileSetFiles method finished", subcomponentId, DateTime.Now);
}
Here are my logs detailing the second method call not starting until the first one has finished:
File Set A: 27/1/2011 11:20:06 PM 11:20:06 PM - Calling ImportSubcomponentFileSetFiles (Silverlight Client)
File Set A: 27/1/2011 11:20:06 PM 11:20:06 PM - ImportSubcomponentFileSetFiles Called (Silverlight Client)
File Set B: 27/1/2011 11:20:06 PM 11:20:06 PM - Calling ImportSubcomponentFileSetFiles (Silverlight Client)
File Set B: 27/1/2011 11:20:06 PM 11:20:06 PM - ImportSubcomponentFileSetFiles Called (Silverlight Client)
File Set A: 01/27/2011 23:20:06 - ImportSubcomponentFileSetFiles method started (Server)
File Set A: 01/27/2011 23:20:06 - ImportFiles Started (Server)
File Set A: 01/27/2011 23:20:23 - ImportFiles Finished (Server)
File Set A: 01/27/2011 23:20:23 - ImportSubcomponentFileSetFiles method finished (Server)
File Set A: 27/1/2011 11:20:23 PM - Import callback recieved (Silverlight Client)
File Set A: 01/27/2011 23:20:23 - GetSubcomponentFileSetWithStatus Started (Server)
File Set A: 01/27/2011 23:20:23 - GetSubcomponentFileSetWithStatus Finished (Server)
File Set B: 01/27/2011 23:20:23 - ImportSubcomponentFileSetFiles method started (Server)
File Set B: 01/27/2011 23:20:23 - ImportFiles Started (Server)
File Set A: 27/1/2011 11:20:23 PM - Refresh callback recieved (Silverlight Client)
File Set B: 01/27/2011 23:20:36 - ImportFiles Finished (Server)
File Set B: 01/27/2011 23:20:36 - ImportSubcomponentFileSetFiles method finished (Server)
File Set B: 27/1/2011 11:20:36 PM - Import callback recieved (Silverlight Client)
File Set B: 01/27/2011 23:20:36 - GetSubcomponentFileSetWithStatus Started (Server)
File Set B: 01/27/2011 23:20:36 - GetSubcomponentFileSetWithStatus Finished (Server)
File Set B: 27/1/2011 11:20:36 PM - Refresh callback recieved (Silverlight Client)
Cheers,
Chris
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为 LinqToEntitiesDomainService 派生自 WCF 类,在这种情况下,可以设置以下 ServiceBehaviour 属性(通过代码或配置):
ServiceBehaviourAttribute.InstanceContextMode:
ServiceBehaviourAttribute.ConcurrencyMode:
这也导致我此声明:
那么,您在客户端上使用的是单个代理吗?您可以创建多个代理吗?或者这是 silverlight 客户端中对您隐藏的东西吗?
I think that LinqToEntitiesDomainService derives from WCF classes, in which case, the following ServiceBehaviour properties might be set (either through code or config):
ServiceBehaviourAttribute.InstanceContextMode:
ServiceBehaviourAttribute.ConcurrencyMode:
This also led me to this statement:
So are you using a single proxy on your client, and could you create multiple ones, or is this something that is hidden from you in the silverlight client?
您没有提到实现 RIA 服务的技术堆栈和/或代码 (
ImportSubcomponentFileSetFiles
) - 从您的 fiddler 跟踪来看,很明显服务器端代码负责串行处理,您需要在那里进行调查相同。对于基于 ASP.NET 的服务,最可能的原因可能是在服务实现中使用会话状态。 ASP.NET 运行时保证一次只有一个请求可以访问会话状态(读/写模式)(以简化编程模型)。
You haven't mentioned the technology stack and/or code implementing your RIA services (
ImportSubcomponentFileSetFiles
) - from your fiddler trace, it clear that server side code is responsible for serial processing and you need to investigate there for the same.For ASP.NET based services, the most probable cause could be use of Session State within service implementation. ASP.NET runtime guarantees that only one request can access Session State (in read/write mode) at a time (to simplify programming model).