虽然我将InstanceContextMode和ConcurrencyMode设置为单一,并且在ServiceThrottlingBehavior中将最大并发调用实例和会话设置为1,但有人可以解释这些问题,我仍然发现至少有2个线程在处理wcf请求吗?
客户输出:
Client name :kk Instance:1 Thread:13 Time:2013/12/30 12:17:56
Client name :kk Instance:1 Thread:12 Time:2013/12/30 12:17:57
Client name :kk Instance:1 Thread:13 Time:2013/12/30 12:17:58
服务器代码:
Uri httpUrl = new Uri("http://localhost:8010/MyService/HelloWorld");
//Create ServiceHost
ServiceHost host
= new ServiceHost(typeof(ClassLibrary1.HelloWorldService), httpUrl);
//Add a service endpoint
host.AddServiceEndpoint(typeof(ClassLibrary1.IHelloWorldService)
, new WSHttpBinding(), "");
//Enable metadata exchange
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
ServiceThrottlingBehavior stb = new ServiceThrottlingBehavior
{
MaxConcurrentCalls = 1,
MaxConcurrentInstances = 1 ,
MaxConcurrentSessions = 1
};
host.Description.Behaviors.Add(smb);
host.Description.Behaviors.Add(stb);
//Start the Service
host.Open();
客户代码:
ServiceReference1.HelloWorldServiceClient obj = new ServiceReference1.HelloWorldServiceClient();
for(int i=0;i<15;i++)
{
obj.Call(str);
Thread.Sleep(1000);
}
服务代码:
[ServiceContract]
public interface IHelloWorldService
{
[OperationContract(IsOneWay=true)]
void Call(string ClientName);
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
public class HelloWorldService : IHelloWorldService
{
public static int i;
public HelloWorldService()
{
i++;
}
public void Call(string ClientName)
{
Console.WriteLine("Client name :" + ClientName + " Instance:" + i.ToString() + " Thread:" + Thread.CurrentThread.ManagedThreadId.ToString() + " Time:" + DateTime.Now.ToString() + "\n\n");
}
}
答案 0 :(得分:4)
我不是线程专家,但我会抓住这个并扩展我的评论。
根据MSDN,ConcurrencyMode.Single表示The service instance is single-threaded and does not accept reentrant calls. If the InstanceContextMode property is Single, and additional messages arrive while the instance services a call, these messages must wait until the service is available or until the messages time out.
您在每次连续呼叫之间延迟1秒钟呼叫您的服务。您的输出也显示了这一点 - 每个呼叫比前一个呼叫晚1秒。
我相信在这种情况下线程id是一个红色的鲱鱼,因为我希望服务使用线程池中的可用线程。我没有在文档中看到任何保证每次都使用相同线程的内容,而且在我看来这将是一个不合理的期望。
如果您期望来自可用线程的专用线程,我认为您不能这样做。如果您希望服务一次只处理一个请求,那么您应该这样做。
答案 1 :(得分:1)
我同意Tim's answer 相同的线程无需为所有调用提供服务。 ConcurencyMode.Single
只能保证一个线程一次为呼叫提供服务。
如果出于某种原因,您需要在WCF服务上使用线程关联,例如,如果您在WinForms / WPF应用程序上运行单件服务,并且您希望服务调用仅在UI线程上运行 - 那么,您只需必须在UI线程上Open
服务主机。 WCF知道SynchronizationContext
,并且只会调用对UI线程的调用,而不管您的ConcurrencyMode
是什么。另请参阅ServiceBehavior
属性的UseSynchronizationContext属性。