单一服务两个绑定但不同绑定的不同行为

时间:2017-07-15 01:36:00

标签: c# wcf

我正在探索WCF实例上下文模式和并发性的更多细节,并对BasicHttpBinding和WSHttpBinding的托管threadID值感到困惑。

[ServiceContract]
public interface IService1
    {
        [OperationContract]
        string GetData(int value);
    }

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, 
                 ConcurrencyMode = ConcurrencyMode.Single)]
 public class Service2 : IService1
    {
        int i;
        public string GetData(int value)
        {
            string output = string.Format("Service2 {0} , {1} , {2}", 
                                          DateTime.Now.ToString(), 
                                          i++, 
                                   System.Threading.Thread.CurrentThread.ManagedThreadId);

            Console.WriteLine(output);            
            System.Threading.Thread.Sleep(5000);
            return output;
        }
}

样品测试

public class program
    {
        [STAThread]
        public static void Main(string[] args)
        {           
            ServiceHost host = new ServiceHost(typeof(Service2), 
                               new Uri("http://localhost:9011"), 
                               new Uri("net.tcp://localhost:9009"));                                  
            host.AddServiceEndpoint(typeof(IService1), 
                                    new BasicHttpBinding(), "");
            host.AddServiceEndpoint(typeof(IService1), 
                                    new WSHttpBinding(), "WS");          

            Test1();
            Console.WriteLine("-------------------------------");
            Test2();
            Console.WriteLine("-------------------------------");            
            Console.ReadLine();
        }

        public static void Test1()
        {
            EndpointAddress endPoint = new EndpointAddress("http://localhost:9011");
            BasicHttpBinding binding = new BasicHttpBinding();
            ChannelFactory<IService1> client = new ChannelFactory<IService1>(binding, endPoint);
            IService1 proxy = client.CreateChannel();
            Enumerable.Range(1, 10).ToList().ForEach(cc =>
            {
                proxy.GetData(10);
            });
        }

        public static void Test2()
        {
            EndpointAddress endPoint = new EndpointAddress("http://localhost:9011/WS");
            WSHttpBinding binding = new WSHttpBinding();
            ChannelFactory<IService1> client = new ChannelFactory<IService1>(binding, endPoint);
            IService1 proxy = client.CreateChannel();
            Enumerable.Range(1, 10).ToList().ForEach(cc =>
            {
                proxy.GetData(10);
            });
        }
     }

现在问题在于ManagedThreadId。

如果查看Test1()的输出,那么所有10的ManagedThreadId值都相同。

但是如果你看一下Test2()那么ManagedThreadId值是不同的。

为什么会这样?

1 个答案:

答案 0 :(得分:0)

InstanceContextModeConcurrencyMode本质上是一个抽象层,它控制服务对象的实例生命周期以及如何对其进行序列化(如果有)和描述线程模型,以确定是否使用相同的线程。

如果我们看一下你的例子:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, 
                 ConcurrencyMode = ConcurrencyMode.Single)]

......这基本上是设置线程安全的;单身人士服务。对于单模并发,所有调用都排队并一次执行一个。 1

自定义线程同步上下文

在我的阅读和经验中,虽然WCF没有说明哪个线程将用于上述属性,但WCF与不同的自定义线程同步上下文兼容虽然这样的实现有:

  

“......与WCF无关”;洛伊,1

OP:

  

如果查看Test1()的输出,那么所有10的ManagedThreadId值都相同。

     

但是如果你看一下Test2()那么ManagedThreadId值是不同的

我会说你看到的所有内容都可能是BasicHttpBinding下的默认服务行为是使用自定义线程池同步器,其中调用排队并依次在相同的线程上执行而在WSHttpBinding下使用默认线程池(因此线程不同的原因)。

更多

enter image description here