项目测试 代码  http://115.com/file/dpi7jj3e# WindowsFormsApplication2.rar也可直接看这个帖子的33楼
http://topic.csdn.net/u/20111229/19/a1101509-1052-4807-83e4-ec3eb4089a22.html
        foreach (var i in Enumerable.Range(1, 10000))
        {
            var taxi = new TaxiInfo { PhoneNumber = i.ToString().PadLeft(12, '0') };
            _taxis.Add(taxi);
        }这个超过25000传输就会异常,不知道为什么。qldsrx这位朋友说知道哪里错了,希望大神出来指点下,谢谢。

解决方案 »

  1.   

    我也想知道到底什么问题。另外还有一项没和lz确认的是,虽然都是 vs2010 你用的是.net 4.0么?
      

  2.   


    恩。。08的项目也没用,这个测试项目是08的项目。。CSDN上传的资源半天显示不出来。
      

  3.   

    是序列化的一个属性MaxItemsInObjectGraph导致了你的问题,那个属性默认值为65536(虽然MSDN上说默认值是Int32.MaxValue,但是我实际检测的结果却是65536),且那个属性不允许修改。为此,只有2个方法可以用,方法一是自定义一个继承IOperationBehavior的属性类,方法二是查找ServiceEndpoint中的Behavior替换。
    方法一:    public class CustomDataContractAttribute : Attribute, IOperationBehavior
        {
            public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
            {
            }
            public void ApplyClientBehavior(OperationDescription description, ClientOperation proxy)
            {
                ReplaceDataContractSerializerOperationBehavior(description);
            }
            public void ApplyDispatchBehavior(OperationDescription description, DispatchOperation dispatch)
            {
                ReplaceDataContractSerializerOperationBehavior(description);
            }
            public void Validate(OperationDescription description)
            {
            }        private static void ReplaceDataContractSerializerOperationBehavior(OperationDescription description)
            {
                DataContractSerializerOperationBehavior dcsOperationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>();
                if (dcsOperationBehavior != null)
                {
                    description.Behaviors.Remove(dcsOperationBehavior);
                    description.Behaviors.Add(new CustomDataContractSerializerOperationBehavior(description));
                }
            }
            public class CustomDataContractSerializerOperationBehavior : DataContractSerializerOperationBehavior
            {
                public CustomDataContractSerializerOperationBehavior(OperationDescription operationDescription)
                    : base(operationDescription)
                {
                    //Console.WriteLine(this.MaxItemsInObjectGraph);
                }
                public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
                {
                    return new DataContractSerializer(type, name, ns, knownTypes, Int32.MaxValue, this.IgnoreExtensionDataObject, false, this.DataContractSurrogate, this.DataContractResolver);
                }
                public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
                {
                    return new DataContractSerializer(type, name, ns, knownTypes, Int32.MaxValue, this.IgnoreExtensionDataObject, false, this.DataContractSurrogate, this.DataContractResolver);            }
            }
        }
        [ServiceContract]
        public interface IService1
        {
            [OperationContract]
            [CustomDataContract]
            List<TaxiInfo> GetAllTaxiInfos();
        }
    方法二:        public class CustomDataContractSerializerOperationBehavior : DataContractSerializerOperationBehavior
            {
                public CustomDataContractSerializerOperationBehavior(OperationDescription operationDescription)
                    : base(operationDescription)
                {
                    //Console.WriteLine(this.MaxItemsInObjectGraph);
                }
                public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
                {
                    return new DataContractSerializer(type, name, ns, knownTypes, Int32.MaxValue, this.IgnoreExtensionDataObject, false, this.DataContractSurrogate, this.DataContractResolver);
                }
                public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
                {
                    return new DataContractSerializer(type, name, ns, knownTypes, Int32.MaxValue, this.IgnoreExtensionDataObject, false, this.DataContractSurrogate, this.DataContractResolver);            }
            }服务端:                ServiceEndpoint ep = _host.AddServiceEndpoint(typeof(IService1), netTcpBinding, strAddress);
                    foreach (OperationDescription op in ep.Contract.Operations)
                    {
                        DataContractSerializerOperationBehavior dataContractBehavior =
                            op.Behaviors.Find<DataContractSerializerOperationBehavior>()
                            as DataContractSerializerOperationBehavior;
                        if (dataContractBehavior != null)
                        {
                            op.Behaviors.Remove(dataContractBehavior);
                            op.Behaviors.Add(new CustomDataContractSerializerOperationBehavior(op));
                        }
                    }
                    _host.Open();客户端:            var channelFactory = new ChannelFactory<IService1>(netbinding, new EndpointAddress("net.tcp://localhost:20000/PositionServices"));            foreach (System.ServiceModel.Description.OperationDescription op in channelFactory.Endpoint.Contract.Operations)
                {
                    System.ServiceModel.Description.DataContractSerializerOperationBehavior dataContractBehavior =
                        op.Behaviors.Find<System.ServiceModel.Description.DataContractSerializerOperationBehavior>()
                        as System.ServiceModel.Description.DataContractSerializerOperationBehavior;
                    if (dataContractBehavior != null)
                    {
                        op.Behaviors.Remove(dataContractBehavior);
                        op.Behaviors.Add(new CustomDataContractSerializerOperationBehavior(op));
                    }
                }            PositionService = channelFactory.CreateChannel();
      

  4.   

    哦其实fangxinggood大神说的也是这个问题。。不过他给的例子是直接改配置文件,我是在代码里面修改的。所以没用吧。。3Q。。WCF ----------------------------Client            
    NetTcpBinding netbinding = new NetTcpBinding(SecurityMode.None, true)
                {
                    MaxBufferPoolSize = 2147483647,
                    MaxBufferSize = 2147483647,
                    MaxReceivedMessageSize = 2147483647,
                    SendTimeout = new TimeSpan(0, 0, 30),
                    ReceiveTimeout = new TimeSpan(20, 0, 0),
                    ReliableSession = { Enabled = false, InactivityTimeout = new TimeSpan(20, 0, 10) },
                    ReaderQuotas =
                    {
                        MaxArrayLength = 2147483647,
                        MaxStringContentLength = 2147483647,
                        MaxBytesPerRead = 2147483647
                    }
                };
                netbinding.TransferMode = TransferMode.Streamed;            ChannelFactory<IPositionService> factory = new ChannelFactory<IPositionService>(netbinding, new EndpointAddress("net.tcp://192.168.0.128:" + Common.ConstParameters.WcfPort + "/PositionServices"));
                foreach (System.ServiceModel.Description.OperationDescription op in factory.Endpoint.Contract.Operations)
                {
                    System.ServiceModel.Description.DataContractSerializerOperationBehavior dataContractBehavior =
                                op.Behaviors.Find<System.ServiceModel.Description.DataContractSerializerOperationBehavior>()
                                as System.ServiceModel.Description.DataContractSerializerOperationBehavior;
                    if (dataContractBehavior != null)
                    {
                        dataContractBehavior.MaxItemsInObjectGraph = 65536000;
                    }
                }           IPositionService ss = factory.CreateChannel();WCF ---------------------------------Service
                    //_host.Description.Endpoints
                    string strAddress = string.Format(@"net.tcp://{0}:" + Common.ConstParameters.WcfPort + "/PositionServices", _serverIp);
                    _host.AddServiceEndpoint(typeof(Service.IPositionService), netTcpBinding, strAddress);                // Find the ContractDescription of the operation to find.
                    ContractDescription cd = _host.Description.Endpoints[0].Contract;
                    OperationDescription myOperationDescription = cd.Operations.Find("test");
                    if(myOperationDescription==null)
                    {
                        myOperationDescription=new OperationDescription("test",_host.Description.Endpoints[0].Contract);
                    }
                    // Find the serializer behavior.
                    DataContractSerializerOperationBehavior serializerBehavior =
                        myOperationDescription.Behaviors.
                           Find<DataContractSerializerOperationBehavior>();
                    // If the serializer is not found, create one and add it.
                    if (serializerBehavior == null)
                    {
                        serializerBehavior = new DataContractSerializerOperationBehavior(myOperationDescription);
                        myOperationDescription.Behaviors.Add(serializerBehavior);
                    }
                    // Change the settings of the behavior.
                    serializerBehavior.MaxItemsInObjectGraph = 65536000;
      

  5.   

    回楼上,我还真没留意部分,毕竟回复内容太多了,所以我自己看着微软的dll反编译的源码琢磨的。
    关于该属性不能修改的解释:我指的是DataContractSerializer里面的那个属性不能修改,至于DataContractSerializerOperationBehavior的没试过。
    另外你是不是客户端和服务端一起改的那个配置,这里需要一起改才行。最后说明下方法一的优势:通过CustomDataContract可以对特定方法单独设置,无需所有方法都开启,同时不需要客户端或服务端在启动代码里做任何改动,使用起来很方便,推荐该方法(同时可扩展性很强)
      

  6.   

    还是有点奇怪,毕竟我后来什么都没加也可以通过。数据可以一直加到OutOfMemory
      

  7.   

    你确定顶楼的代码你下载后运行也是可以通过吗?实际项目不同,估计里面也会有一些差异的。
    不过那个MaxItemsInObjectGraph属性的确是微软的BUG,因为MSDN里面各个版本都写着默认值Int32.MaxValue的,结果却不是,这明显是在误导。
      

  8.   


    是我弄错了我把DataContractSerializer弄成DataContractSerializerOperationBehavior了所以没用。。我刚刚测试了下直接设置他的属性是可以的。------------------------------------------WCF Serveice-------------------------------------
                         foreach (OperationDescription op in ep.Contract.Operations)
                         {
                             DataContractSerializerOperationBehavior dataContractBehavior =
                                 op.Behaviors.Find<DataContractSerializerOperationBehavior>()
                                 as DataContractSerializerOperationBehavior;
                             if (dataContractBehavior != null)
                             {
                                 dataContractBehavior.MaxItemsInObjectGraph = 65535000;
                                 //op.Behaviors.Remove(dataContractBehavior);
                                 //op.Behaviors.Add(new CustomDataContractSerializerOperationBehavior(op));
                             }
                         }---------------------------------------WCF CLient---------------------------------------
                var channelFactory = new ChannelFactory<IService1>(netbinding, new EndpointAddress("net.tcp://localhost:20000/PositionServices"));            foreach (System.ServiceModel.Description.OperationDescription op in channelFactory.Endpoint.Contract.Operations)
                {
                    System.ServiceModel.Description.DataContractSerializerOperationBehavior dataContractBehavior =
                        op.Behaviors.Find<System.ServiceModel.Description.DataContractSerializerOperationBehavior>()
                        as System.ServiceModel.Description.DataContractSerializerOperationBehavior;
                    if (dataContractBehavior != null)
                    {
                        dataContractBehavior.MaxItemsInObjectGraph = 65535000;
                        //op.Behaviors.Remove(dataContractBehavior);
                        //op.Behaviors.Add(new CustomDataContractSerializerOperationBehavior(op));
                    }
                }
    感谢楼上2位的关注,谢了。