我有一个WCF服务,我用它来替换旧的ASP.NET Web服务。该服务似乎工作正常,但由于某种原因无法处理同时发出的请求。我的服务实现具有以下属性:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class HHService : IHHService
我的主持人声明如下:
baseAddress = new Uri("http://0.0.0.0:8888/HandHeld/");
host = new ServiceHost(typeof(HHService), baseAddress);
ServiceMetadataBehavior behavior;
behavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (behavior == null)
{
behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
behavior.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(behavior);
}
host.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
host.AddServiceEndpoint(typeof(IHHService), new BasicHttpBinding(), "HHService.asmx");
HHService.LogMessage += new EventHandler<HHService.LogMessageEventArgs>(HHService_LogMessage);
host.Open();
服务运行并返回正确的结果,但如果两个客户端尝试同时进行呼叫,则一个客户端将阻塞,直到另一个客户端完成而不是一起执行的调用。我没有使用任何配置文件。我正在尝试以编程方式执行所有操作。我是否有错误的设置导致此行为?我使用NetTCPBinding运行其他服务没有这个问题。
修改 回应John Saunders: 我不熟悉任何ASP.NET兼容模式。我没有使用任何会话状态,服务是无状态的,它只处理请求。除了实际方法的实现之外,我所做的其他一切都在这里列出的代码中。
可能的解决方案:
我正在从主窗体的form_load事件中调用host.Open()
函数。我将调用移动到一个单独的线程。所有这个线程都是调用host.Open()
,但现在服务看起来像我期望的那样。
答案 0 :(得分:4)
如果您的实例上下文模式是PerCall,那么您的服务器始终是单线程的,因为根据定义,每个调用都会获得一个新的服务器实例。
这在IIS环境中运行正常,IIS可以启动多个服务器实例来处理n个并发调用者,每个调用者作为每个传入请求的单线程服务器。
您在一条评论中提到您在表单应用程序中托管WCF - 这可能是您需要重新考虑的设计决策 - 这不是最佳选择,因为Winforms应用程序无法轻松处理多个调用方并启动多个实例服务代码。
马克
答案 1 :(得分:0)
您的服务功能中是否存在锁?
答案 2 :(得分:0)
您使用的是ASP.NET兼容模式吗?会话状态?
我的下一个问题是:是什么让你认为它是单线程的?您是如何确定的,以及您使用什么测试来证明您没有解决问题?可能是误报。
答案 3 :(得分:0)
另一个问题回答了这个问题:
[ServiceBehavior(UseSynchronizationContext = false)]