none
WCF阻塞的问题,如何解决这类问题. RRS feed

  • 问题

  • Wcf宿主采用的CS程序,没有采用iis,服务绑定的是net:tcp协议.项目中有双工回调的机制,但是这里出现的阻塞并没有用到这个双工回调.

    过程是我从客户端调用服务的一个函数执行业务,服务端的这个函数需要开启程序级别事务去对数据库操作,(这里不是wcf的那种分布式事务),操作完毕后函数返回值为bool,但是所执行的业务可能出现很长时间大约1分钟左右,问题就是在执行这1分钟时间内,其他客户端调用这个服务端的服务被挂起好像阻塞一样(客户端就好比假死一样),需要等到这个服务运行完成才可以继续下去,wcf服务在执行大量并发时候是不是都必须像排队一样一个一个执行呢?

    2014年2月17日 3:38

答案

全部回复

  • 首先谢谢你的回答,我这几天根据你提供的资料也查询一些但是还存在一些问题没有解决,还请大家分析下,以下是我的实现事例:

    [ServiceBehavior(
           MaxItemsInObjectGraph = int.MaxValue,
           InstanceContextMode = InstanceContextMode.PerCall,
           ConcurrencyMode = ConcurrencyMode.Single)]
        public class Service1 : IService1
        {
           public string GetDataValue()
            {
                  return string.Format("获取返回值");
            }
            public string GetDataValueTime()
            {
                Thread.Sleep(5000);
                return string.Format("5秒后获取返回值CS");
            }
        }
        [ServiceContract]
        public interface IService1
        { 
            [OperationContract]
            string GetDataValue();
            [OperationContract]
            string GetDataValueTime();
      }
    //采用的cs端做宿主,这是启动方法
        private void simpleButton1_Click(object sender, EventArgs e)
            {           
         
                try
                {
                     Uri url = new Uri(String.Format("http://192.168.1.100:777",""));
                    ServiceHost host = new ServiceHost(typeof(Service1), url);
                      WSHttpBinding binding = new WSHttpBinding();
                    host.AddServiceEndpoint(typeof(IService1), binding, url);
                    
                  if (host.Description.Behaviors.Find<System.ServiceModel.Description.ServiceMetadataBehavior>() == null)
                    {
                                         //设置行为
                        ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
                        behavior.HttpGetUrl = url;
                        behavior.HttpGetEnabled = true;
                        host.Description.Behaviors.Add(behavior);
                   }
                                    host.Open();
                 }
                catch (Exception ex)
                {
                }
              
            }

    客户端做了一个调用,采用的winform放了两个按钮分别调用服务端的两个方法,其中一个要停顿5秒一个直接返回结果.

    我同时打开两个测试的exe,分别在两个exe程序里面点击不同调用时候,发现在调用有停顿的方法时候另一个直接返回的方法也需要等待前一个调用完毕才有返回数据.

       private void simpleButton1_Click(object sender, EventArgs e)
            {
                ServiceReference1.Service1Client service = new ServiceReference1.Service1Client();
                this.textEdit1.Text = service.GetDataValueTime();
            }
            private void simpleButton2_Click(object sender, EventArgs e)
            {
                ServiceReference1.Service1Client service = new ServiceReference1.Service1Client();
                this.textEdit1.Text = service.GetDataValue();
            }

    问题就出现在我开两个exe可以理解为两个客户端,分别调用服务端应该不影响,现在感觉服务端好像单线程,请问如何处理.

    我设置这个属性多种组合方式都没达到效果

    [ServiceBehavior(
           MaxItemsInObjectGraph = int.MaxValue,
           InstanceContextMode = InstanceContextMode.PerCall,
           ConcurrencyMode = ConcurrencyMode.Single)]

    2014年2月21日 8:58
  • 同样的服务端我采用iis做宿主,没有出现这类问题可以分别调用不会阻断.
    2014年2月21日 8:59
    • 已标记为答案 zzjjff 2014年2月24日 4:00
    2014年2月21日 9:05
  • 试一下把ConcurrencyMode改为ConcurrencyMode.Multiple
    2014年2月21日 9:47
  • 原来是属于宿主产生的问题,宿主winform的情况下就好比单线程一样在调用过程中会出现UI阻断,除非采用多线程处理,相比寄宿的WCF服务需要调整属性来控制

    2014年2月24日 5:21