none
wcf接口延时响应的问题 RRS feed

  • 问题

  • 在大并发的情况下,客户端的操作请求到达服务端会延时(有时达到20几秒),例如,客户端在9:00:00调用服务端的DoWork(),服务端得到这个请求的时间会9:00:20。

    说明:我的服务端设置    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]

    跪求解决办法。

    2009年12月15日 2:38

答案

全部回复

  • 没有人关注过???

    想知道导致这种问题的原因大概有哪些方面。

    2009年12月16日 6:07
  • 我没猜错的话,应该是你使用Wcf代理客户端的方式问题。

    对同一个服务,通道创建一次即可,然后并发调用。

    不要使用工具生成的客户端代理,而是自己写代理类。

    2009年12月16日 12:30
  • 客户端 如何做的测试?

    Frank Xu Lei--谦卑若愚,好学若饥
    专注于.NET平台下分布式应用系统开发和企业应用系统集成
    Focus on Distributed Applications Development and EAI based on .NET
    欢迎访问老徐的中文技术博客:Welcome to My Chinese Technical Blog
    欢迎访问微软WCF中文技术论坛:Welcome to Microsoft Chinese WCF Forum
    欢迎访问微软WCF英文技术论坛:Welcome to Microsoft English WCF Forum
    2009年12月16日 15:51
    版主
  • 网络环境为:150客户端分别连了3个交换机,然后这三个交换机连一个中心交换机,最后中心交换机再连服务器交换机,即客户端到服务端有3个交换机.

    150人并发调用服务端,有时会出现延时现象。比如说服务端提供10个操作接口,一天下来,每个接口都有可能出现延时现象,从调用接口次数的比例来说大概是1/500左右,即500次调用会出现一次延时现象。时间是通过日志记录的

    2009年12月17日 2:22
  • 二楼的Galactica 遇到过类似问题??能详细描叙一下吗??这个问题很头疼,很多即时业务都超时了。谢了!
    2009年12月17日 2:26
  • 你把我说糊涂了.你的第二次回答,让我不知道你到底出了什么问题。
    你得把绑定贴出来.

    我说的问题描述如下:

    用工具生成的代理类 ServiceClient.

    1, 创建一个实例:ServiceClient client = new ServiceClient();
    然后用150个线程去跑 client.DoWork(),那么客户端的150个线程间会相互阻塞。


    1, 创建150个线程,每个线程创建一个实例:ServiceClient client = new ServiceClient();
    然后用150个线程去跑 client.DoWork(),那么客户端的150个线程间也会相互阻塞。

    解决办法是,按如下代码写客户端代理类:

    public class ServiceClient : IService
    {
            public ServiceClient ()
            {
                try
                {
                    if (_channel != null)
                        ((IChannel)_channel).Abort();
                    if (_factory != null)
                        _factory.Abort();
                    _channel = null;
                    _factory = null;
                }
                catch
                { }
            }

            static private string _address;
            private static string binding;
            static public string Address
            {
                set
                {
                    _address = value;
                }
                get
                {
                    return _address;
                }
            }
           
             private static object _channelLock = new object();        
             private static ChannelFactory<IService> _factory;
             private static ITradeServices _channel;

             //the public property that allows the static instances to be safely shared.  It provides
             //the necessary locking logic to ensure the channel is valid, and if not, destroy it so it
             //can be re-initialized in a subsequent call.
             public IService Channel
             {
                 get
                 {
                     IService localChannel = _channel;
                     if (localChannel == null)
                     {
                         lock (_channelLock)
                         {
                             if (_factory == null)
                             {
                                 if (_address.Contains("net.tcp"))
                                     binding = "CustomTcpBinding_PrimaryService";
                                 else
                                     binding = "BasicHttpBinding_PrimaryService";
                                 _factory = new ChannelFactory<IService>(binding, new EndpointAddress( _address ));
                             }
                             if (_channel == null)
                             {
                                 _channel = _factory.CreateChannel();
                             }
                             return _channel;
                         }
                     }
                     return localChannel;
                 }
                 set
                 {
                     lock (_channelLock)
                     {
                         if (((IChannel)_channel).State != CommunicationState.Opened)
                         {
                             ((IChannel)_channel).Abort();
                             _channel = null;
                             if (_factory.State != CommunicationState.Opened)
                             {
                                 _factory.Abort();
                                 _factory = null;
                             }
                         }
                     }
                 }
             }

       public void DoWork()
      {
         try
        {
           return this.Channel.DoWork();
         }
         catch
         {
           this.Channel =null;
           throw;
           }
       }
    }


    2009年12月17日 10:21
  • Galactica 您好!
    客户端配置:
      <system.serviceModel>
        <bindings>
          <netTcpBinding>
            <binding name="NetTcpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
              receiveTimeout="00:10:00" sendTimeout="00:00:05" transactionFlow="false"
              transferMode="Buffered" transactionProtocol="OleTransactions"
              hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="52428800"
              maxBufferSize="65536000" maxConnections="1000" maxReceivedMessageSize="65536000">
              <readerQuotas maxDepth="65535000" maxStringContentLength="65535000"
                maxArrayLength="65535000" maxBytesPerRead="65535000" maxNameTableCharCount="65535000" />
              <reliableSession ordered="true" inactivityTimeout="00:10:00"
                enabled="false" />
              <security mode="None" />
            </binding>
          </netTcpBinding>
        </bindings>
        <client>
          <endpoint address="net.tcp://10.0.0.5:8731/" binding="netTcpBinding"
            bindingConfiguration="NetTcpEndpoint" contract="Test.ITasksService"
            name="NetTcpEndpoint">
            <identity>
              <userPrincipalName value="SKO\Winston" />
            </identity>
          </endpoint>
        </client>
      </system.serviceModel>

    服务端配置:
     <system.serviceModel>
        <bindings>
          <netTcpBinding>
            <binding name="NetTcpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
              receiveTimeout="00:10:00" sendTimeout="00:00:05" transactionFlow="false"
              transferMode="Buffered" transactionProtocol="OleTransactions"
              hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="52428800"
              maxBufferSize="65536000" maxConnections="1000" maxReceivedMessageSize="65536000">
              <readerQuotas maxDepth="65535000" maxStringContentLength="65535000"
                maxArrayLength="65535000" maxBytesPerRead="65535000" maxNameTableCharCount="65535000" />
              <reliableSession ordered="true" inactivityTimeout="00:10:00"
                enabled="false" />
              <security mode="None" />
            </binding>
          </netTcpBinding>
        </bindings>
        <client>
          <endpoint address="net.tcp://10.0.0.5:8731/" binding="netTcpBinding"
            bindingConfiguration="NetTcpEndpoint" contract="Test.ITasksService"
            name="NetTcpEndpoint">
            <identity>
              <userPrincipalName value="SKO\Winston" />
            </identity>
          </endpoint>
        </client>
      </system.serviceModel>

    还有我客户端跟服务端是双工的,请问该怎么写代理类?


    以下是我工具生成的:
    namespace InputTest.Test {
        using System.Runtime.Serialization;
        using System;
       
       
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
        [System.Runtime.Serialization.DataContractAttribute(Name="Task", Namespace="http://schemas.datacontract.org/2004/07/EngineWCFService")]
        [System.SerializableAttribute()]
        public partial class Task : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
           
            [System.NonSerializedAttribute()]
            private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private int BaseIDField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private string BatchIDField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private string IDField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private string OperIDField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private string SkillIDField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private string SkillsField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private string TaskXmlField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private int TimeField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private int WorkIDField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private int WorkTimeField;
           
            [global::System.ComponentModel.BrowsableAttribute(false)]
            public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
                get {
                    return this.extensionDataField;
                }
                set {
                    this.extensionDataField = value;
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public int BaseID {
                get {
                    return this.BaseIDField;
                }
                set {
                    if ((this.BaseIDField.Equals(value) != true)) {
                        this.BaseIDField = value;
                        this.RaisePropertyChanged("BaseID");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string BatchID {
                get {
                    return this.BatchIDField;
                }
                set {
                    if ((object.ReferenceEquals(this.BatchIDField, value) != true)) {
                        this.BatchIDField = value;
                        this.RaisePropertyChanged("BatchID");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string ID {
                get {
                    return this.IDField;
                }
                set {
                    if ((object.ReferenceEquals(this.IDField, value) != true)) {
                        this.IDField = value;
                        this.RaisePropertyChanged("ID");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string OperID {
                get {
                    return this.OperIDField;
                }
                set {
                    if ((object.ReferenceEquals(this.OperIDField, value) != true)) {
                        this.OperIDField = value;
                        this.RaisePropertyChanged("OperID");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string SkillID {
                get {
                    return this.SkillIDField;
                }
                set {
                    if ((object.ReferenceEquals(this.SkillIDField, value) != true)) {
                        this.SkillIDField = value;
                        this.RaisePropertyChanged("SkillID");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string Skills {
                get {
                    return this.SkillsField;
                }
                set {
                    if ((object.ReferenceEquals(this.SkillsField, value) != true)) {
                        this.SkillsField = value;
                        this.RaisePropertyChanged("Skills");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string TaskXml {
                get {
                    return this.TaskXmlField;
                }
                set {
                    if ((object.ReferenceEquals(this.TaskXmlField, value) != true)) {
                        this.TaskXmlField = value;
                        this.RaisePropertyChanged("TaskXml");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public int Time {
                get {
                    return this.TimeField;
                }
                set {
                    if ((this.TimeField.Equals(value) != true)) {
                        this.TimeField = value;
                        this.RaisePropertyChanged("Time");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public int WorkID {
                get {
                    return this.WorkIDField;
                }
                set {
                    if ((this.WorkIDField.Equals(value) != true)) {
                        this.WorkIDField = value;
                        this.RaisePropertyChanged("WorkID");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public int WorkTime {
                get {
                    return this.WorkTimeField;
                }
                set {
                    if ((this.WorkTimeField.Equals(value) != true)) {
                        this.WorkTimeField = value;
                        this.RaisePropertyChanged("WorkTime");
                    }
                }
            }
           
            public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
           
            protected void RaisePropertyChanged(string propertyName) {
                System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
                if ((propertyChanged != null)) {
                    propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
                }
            }
        }
       
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
        [System.Runtime.Serialization.DataContractAttribute(Name="TaskResult", Namespace="http://schemas.datacontract.org/2004/07/EngineWCFService")]
        [System.SerializableAttribute()]
        public partial class TaskResult : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
           
            [System.NonSerializedAttribute()]
            private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private string BatchIDField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private int ChineseBitField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private int EnglishBitField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private System.DateTime FinishTimeField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private string IDField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private string OperIDField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private int QuestionNumField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private string ResultXmlField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private string SkillIDField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private string TradeIDField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private int WorkIDField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private int WorkTimeField;
           
            [global::System.ComponentModel.BrowsableAttribute(false)]
            public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
                get {
                    return this.extensionDataField;
                }
                set {
                    this.extensionDataField = value;
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string BatchID {
                get {
                    return this.BatchIDField;
                }
                set {
                    if ((object.ReferenceEquals(this.BatchIDField, value) != true)) {
                        this.BatchIDField = value;
                        this.RaisePropertyChanged("BatchID");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public int ChineseBit {
                get {
                    return this.ChineseBitField;
                }
                set {
                    if ((this.ChineseBitField.Equals(value) != true)) {
                        this.ChineseBitField = value;
                        this.RaisePropertyChanged("ChineseBit");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public int EnglishBit {
                get {
                    return this.EnglishBitField;
                }
                set {
                    if ((this.EnglishBitField.Equals(value) != true)) {
                        this.EnglishBitField = value;
                        this.RaisePropertyChanged("EnglishBit");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public System.DateTime FinishTime {
                get {
                    return this.FinishTimeField;
                }
                set {
                    if ((this.FinishTimeField.Equals(value) != true)) {
                        this.FinishTimeField = value;
                        this.RaisePropertyChanged("FinishTime");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string ID {
                get {
                    return this.IDField;
                }
                set {
                    if ((object.ReferenceEquals(this.IDField, value) != true)) {
                        this.IDField = value;
                        this.RaisePropertyChanged("ID");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string OperID {
                get {
                    return this.OperIDField;
                }
                set {
                    if ((object.ReferenceEquals(this.OperIDField, value) != true)) {
                        this.OperIDField = value;
                        this.RaisePropertyChanged("OperID");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public int QuestionNum {
                get {
                    return this.QuestionNumField;
                }
                set {
                    if ((this.QuestionNumField.Equals(value) != true)) {
                        this.QuestionNumField = value;
                        this.RaisePropertyChanged("QuestionNum");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string ResultXml {
                get {
                    return this.ResultXmlField;
                }
                set {
                    if ((object.ReferenceEquals(this.ResultXmlField, value) != true)) {
                        this.ResultXmlField = value;
                        this.RaisePropertyChanged("ResultXml");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string SkillID {
                get {
                    return this.SkillIDField;
                }
                set {
                    if ((object.ReferenceEquals(this.SkillIDField, value) != true)) {
                        this.SkillIDField = value;
                        this.RaisePropertyChanged("SkillID");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string TradeID {
                get {
                    return this.TradeIDField;
                }
                set {
                    if ((object.ReferenceEquals(this.TradeIDField, value) != true)) {
                        this.TradeIDField = value;
                        this.RaisePropertyChanged("TradeID");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public int WorkID {
                get {
                    return this.WorkIDField;
                }
                set {
                    if ((this.WorkIDField.Equals(value) != true)) {
                        this.WorkIDField = value;
                        this.RaisePropertyChanged("WorkID");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public int WorkTime {
                get {
                    return this.WorkTimeField;
                }
                set {
                    if ((this.WorkTimeField.Equals(value) != true)) {
                        this.WorkTimeField = value;
                        this.RaisePropertyChanged("WorkTime");
                    }
                }
            }
           
            public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
           
            protected void RaisePropertyChanged(string propertyName) {
                System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
                if ((propertyChanged != null)) {
                    propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
                }
            }
        }
       
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
        [System.Runtime.Serialization.DataContractAttribute(Name="Image", Namespace="http://schemas.datacontract.org/2004/07/EngineWCFService")]
        [System.SerializableAttribute()]
        public partial class Image : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
           
            [System.NonSerializedAttribute()]
            private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private string ExtendField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private string ImageIDField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private string[] ImageNameField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private byte[][] ImgDataField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private byte[] MACField;
           
            [System.Runtime.Serialization.OptionalFieldAttribute()]
            private int[] PageField;
           
            [global::System.ComponentModel.BrowsableAttribute(false)]
            public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
                get {
                    return this.extensionDataField;
                }
                set {
                    this.extensionDataField = value;
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string Extend {
                get {
                    return this.ExtendField;
                }
                set {
                    if ((object.ReferenceEquals(this.ExtendField, value) != true)) {
                        this.ExtendField = value;
                        this.RaisePropertyChanged("Extend");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string ImageID {
                get {
                    return this.ImageIDField;
                }
                set {
                    if ((object.ReferenceEquals(this.ImageIDField, value) != true)) {
                        this.ImageIDField = value;
                        this.RaisePropertyChanged("ImageID");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public string[] ImageName {
                get {
                    return this.ImageNameField;
                }
                set {
                    if ((object.ReferenceEquals(this.ImageNameField, value) != true)) {
                        this.ImageNameField = value;
                        this.RaisePropertyChanged("ImageName");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public byte[][] ImgData {
                get {
                    return this.ImgDataField;
                }
                set {
                    if ((object.ReferenceEquals(this.ImgDataField, value) != true)) {
                        this.ImgDataField = value;
                        this.RaisePropertyChanged("ImgData");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public byte[] MAC {
                get {
                    return this.MACField;
                }
                set {
                    if ((object.ReferenceEquals(this.MACField, value) != true)) {
                        this.MACField = value;
                        this.RaisePropertyChanged("MAC");
                    }
                }
            }
           
            [System.Runtime.Serialization.DataMemberAttribute()]
            public int[] Page {
                get {
                    return this.PageField;
                }
                set {
                    if ((object.ReferenceEquals(this.PageField, value) != true)) {
                        this.PageField = value;
                        this.RaisePropertyChanged("Page");
                    }
                }
            }
           
            public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
           
            protected void RaisePropertyChanged(string propertyName) {
                System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
                if ((propertyChanged != null)) {
                    propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
                }
            }
        }
       
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
        [System.ServiceModel.ServiceContractAttribute(ConfigurationName="Test.ITasksService", CallbackContract=typeof(InputTest.Test.ITasksServiceCallback))]
        public interface ITasksService {
           
            [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://tempuri.org/ITasksService/DoWork")]
            void DoWork();
           
            [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://tempuri.org/ITasksService/getTask")]
            void getTask(InputTest.Test.Task task);
           
            [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITasksService/submitResult", ReplyAction="http://tempuri.org/ITasksService/submitResultResponse")]
            bool submitResult(InputTest.Test.TaskResult result);
           
            [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITasksService/checkOper", ReplyAction="http://tempuri.org/ITasksService/checkOperResponse")]
            int checkOper(string operId, string password, ref string groupids, ref string name, ref string team, ref string starlevel);
           
            [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITasksService/pauseOper", ReplyAction="http://tempuri.org/ITasksService/pauseOperResponse")]
            bool pauseOper(string operId);
           
            [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITasksService/restartOper", ReplyAction="http://tempuri.org/ITasksService/restartOperResponse")]
            bool restartOper(string operId);
           
            [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITasksService/exitOper", ReplyAction="http://tempuri.org/ITasksService/exitOperResponse")]
            bool exitOper(string operId);
           
            [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITasksService/workMoveBack", ReplyAction="http://tempuri.org/ITasksService/workMoveBackResponse")]
            bool workMoveBack(string operId, int workId, string batchid, char status);
           
            [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITasksService/AppDelay", ReplyAction="http://tempuri.org/ITasksService/AppDelayResponse")]
            void AppDelay(System.Collections.Generic.Queue<string[]> task, int span);
           
            [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://tempuri.org/ITasksService/UpdateRecoveryTime")]
            void UpdateRecoveryTime(System.Collections.Generic.Queue<string[]> task);
           
            [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITasksService/GetImage", ReplyAction="http://tempuri.org/ITasksService/GetImageResponse")]
            InputTest.Test.Image[] GetImage(string[] imageid, string id);
           
            [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITasksService/SearchInfo", ReplyAction="http://tempuri.org/ITasksService/SearchInfoResponse")]
            System.Data.DataSet SearchInfo(string sql);
           
            [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITasksService/UpdateInfo", ReplyAction="http://tempuri.org/ITasksService/UpdateInfoResponse")]
            void UpdateInfo(string sql);
        }
       
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
        public interface ITasksServiceCallback {
           
            [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITasksService/SendTask", ReplyAction="http://tempuri.org/ITasksService/SendTaskResponse")]
            bool SendTask(InputTest.Test.Task task);
        }
       
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
        public interface ITasksServiceChannel : InputTest.Test.ITasksService, System.ServiceModel.IClientChannel {
        }
       
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
        public partial class TasksServiceClient : System.ServiceModel.DuplexClientBase<InputTest.Test.ITasksService>, InputTest.Test.ITasksService {
           
            public TasksServiceClient(System.ServiceModel.InstanceContext callbackInstance) :
                    base(callbackInstance) {
            }
           
            public TasksServiceClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName) :
                    base(callbackInstance, endpointConfigurationName) {
            }
           
            public TasksServiceClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, string remoteAddress) :
                    base(callbackInstance, endpointConfigurationName, remoteAddress) {
            }
           
            public TasksServiceClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
                    base(callbackInstance, endpointConfigurationName, remoteAddress) {
            }
           
            public TasksServiceClient(System.ServiceModel.InstanceContext callbackInstance, System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
                    base(callbackInstance, binding, remoteAddress) {
            }
           
            public void DoWork() {
                base.Channel.DoWork();
            }
           
            public void getTask(InputTest.Test.Task task) {
                base.Channel.getTask(task);
            }
           
            public bool submitResult(InputTest.Test.TaskResult result) {
                return base.Channel.submitResult(result);
            }
           
            public int checkOper(string operId, string password, ref string groupids, ref string name, ref string team, ref string starlevel) {
                return base.Channel.checkOper(operId, password, ref groupids, ref name, ref team, ref starlevel);
            }
           
            public bool pauseOper(string operId) {
                return base.Channel.pauseOper(operId);
            }
           
            public bool restartOper(string operId) {
                return base.Channel.restartOper(operId);
            }
           
            public bool exitOper(string operId) {
                return base.Channel.exitOper(operId);
            }
           
            public bool workMoveBack(string operId, int workId, string batchid, char status) {
                return base.Channel.workMoveBack(operId, workId, batchid, status);
            }
           
            public void AppDelay(System.Collections.Generic.Queue<string[]> task, int span) {
                base.Channel.AppDelay(task, span);
            }
           
            public void UpdateRecoveryTime(System.Collections.Generic.Queue<string[]> task) {
                base.Channel.UpdateRecoveryTime(task);
            }
           
            public InputTest.Test.Image[] GetImage(string[] imageid, string id) {
                return base.Channel.GetImage(imageid, id);
            }
           
            public System.Data.DataSet SearchInfo(string sql) {
                return base.Channel.SearchInfo(sql);
            }
           
            public void UpdateInfo(string sql) {
                base.Channel.UpdateInfo(sql);
            }
        }
    }

    您说的手写代理类是不是就只要重写横线部分?

    2009年12月17日 11:44
  •     public class WcfClientBase<TChannel> where TChannel : class
        {
            private static object _channelLock = new object();
            private static ChannelFactory<TChannel> _factory;
            private static TChannel _channel;
            private string _endpoint;
            private string _bindingConfig;
    
            public WcfClientBase(string endpoint, string bindingConfig)
            {
                _endpoint = endpoint;
                _bindingConfig = bindingConfig;
            }
    
            public TChannel Channel
            {
                get
                {
                    TChannel localChannel = _channel;
                    if (localChannel == null)
                    {
                        lock (_channelLock)
                        {
                            if (_channel != null)
                                return _channel;
                            if (_factory == null)
                            {
                                try
                                {
                                    EndpointAddress remoteNodeEndPointAddress = new EndpointAddress(_endpoint);
                                    _factory = new ChannelFactory<TChannel>(_bindingConfig, remoteNodeEndPointAddress);
                                }
                                catch
                                {
                                    throw;
                                }
                            }
                            _channel = _factory.CreateChannel();
                            //Note:  VERY important to call open here, fix from prior releases where open was not called,
                            //resulting in spotty client-side bottleneck when clients run many threads.
                            ((IChannel)_channel).Open();
                            return _channel;
                        }
                    }
                    return localChannel;
                }
                set
                {
                    lock (_channelLock)
                    {
                        if (_channel != null && ((IChannel)_channel).State != CommunicationState.Opened)
                        {
                            ((IChannel)_channel).Abort();
                            _channel = null;
                            if (_factory != null && _factory.State != CommunicationState.Opened)
                            {
                                _factory.Abort();
                                _factory = null;
                            }
                        }
                    }
                }
            }
    
            public void Open()
            {
                TChannel localChannel = this.Channel;
            }
    
            public void Close()
            {
                lock (_channelLock)
                {
                    if (_channel != null)
                    {
                        try
                        {
                            ((IChannel)_channel).Close();
    
                        }
                        catch
                        {
                            ((IChannel)_channel).Abort();
    
                        }
                    }
                    if (_factory != null)
                    {
                        try
                        {
                            _factory.Close();
                        }
                        catch
                        {
                            _factory.Abort();
                        }
                    }
                    _channel = null;
                    _factory = null;
                }
            }
        }
    简单写了个基类,你的客户端代理从这个类继承,如下:
    public class TasksServiceClient: WcfClientBase<ITasksService>, ITasksService
        {      
            public TasksServiceClient(string endpoint, string bindingConfig)
                : base(endpoint, bindingConfig)
            {
            }
    
            #region ITasksService成员
            
            public void DoWork()
            {
                try
                {
                    return this.Channel.DoWork();
                }
                catch
                {
                    this.Channel = null;
                    throw;
                }
            }
    
            // 你的其它方法,略.
            
            #endregion
        }
    调用方式:
    public void TestDoWork()
    {
        TasksServiceClient client =new TasksServiceClient("服务终结点地址","客户端终结点配置名称");
        client.DoWork();
    }

    这是个线程安全的方法,你不用管 client.Open 和 client.Close.
    然后使用 VS的负载测试工具,测试 TestDoWork 方法。
    测试设置 150 个用户,运行 1 小时,查看响应时间。
    2009年12月18日 3:03
  • Chenzhit 你好,

    你的代码中没有提供服务器端的服务配置文件。我猜测一下,你可能没有配置 "ServiceThrottling" 这个servicebehavior。
    默认设置中,服务同时处理的call并发上限为16,session并发上限为10。并发多的话,服务响应延迟会变高,性能会很搓的。

    关于ServiceThrottling的信息,应参考这篇文档
    http://msdn.microsoft.com/en-us/library/ms731379.aspx
    Mog Liang
    2009年12月18日 5:29
  • 多谢Galactica ,我先试下!
    2009年12月21日 1:14
  • 版主好!
          您说的配置我配了,配置如下:
          <serviceBehaviors>
            <behavior name="EngineWCFService.TasksServiceBehavior">
              <serviceDebug includeExceptionDetailInFaults="true" />
              <serviceThrottling maxConcurrentCalls="10000" maxConcurrentSessions="10000"
                maxConcurrentInstances="10000" />
              <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8001" />
            </behavior>
          </serviceBehaviors>

    不知最大值是多少?

    2009年12月21日 1:16
  • 参考这篇文档
    http://msdn.microsoft.com/en-us/library/ms731379.aspx
    最大值是Int32.MaxValue.


    Mog Liang
    2009年12月21日 2:35
  • 版主好!
         写了个测试程序去测serviceThrottling ,感觉没用。
          我的设置如下:<serviceThrottling maxConcurrentCalls="10000" maxConcurrentSessions="10000"
                maxConcurrentInstances="10000" />
          循环启动10000个线程去调服务端接口(服务端客户端在同一台机器上),接口里面的动作延时5s就结束。
          运行的现象如下:
          客户端:到500多个的时候会停顿20多秒,接下来每100~200会停顿20几秒。
          服务端:打出的每次调用时间延时从0~1000毫秒不等(大部分400ms以上)。
          
          我把测试程序发出,请帮忙看看。
          下载地址:
          http://cid-45cad4abc91d67f0.skydrive.live.com/self.aspx/.Public/Test.rar

    2009年12月22日 2:06
  • 我写例子测试了一下,有效果的。但是并发性能不止和这些参数有关,机器性能也有很大关系。我把并发数设10000,也会有call返回服务器忙的错误。
    这里有一些控制资源使用,提高性能以及wcf性能检测工具的文章,你有兴趣的话看一看。
    http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/5795ffb6-6395-4a50-b6e8-03a398b75c1b/
    http://msdn.microsoft.com/en-us/library/ms735098.aspx
    http://msdn.microsoft.com/en-us/library/bb463275(VS.100).aspx


    Mog Liang
    2009年12月22日 5:54
  • Hi,
    如果不配置限流,我以前测试的10个客户端同时调用的时候,就会出错。
    直接死锁。
    Frank Xu Lei--谦卑若愚,好学若饥
    专注于.NET平台下分布式应用系统开发和企业应用系统集成
    Focus on Distributed Applications Development and EAI based on .NET
    欢迎访问老徐的中文技术博客:Welcome to My Chinese Technical Blog
    欢迎访问微软WCF中文技术论坛:Welcome to Microsoft Chinese WCF Forum
    欢迎访问微软WCF英文技术论坛:Welcome to Microsoft English WCF Forum
    2009年12月22日 12:19
    版主
  • 郁闷,按Galactica的方法试了还是有延时。难道无解?

    2009年12月24日 1:40