Using the default DataContractSerializer of WCF to manually serialize the data to byte [], and then manually deserialize the data after receiving the data, this problem can be solved. That is to say, if only byte [] can be used in the past, the list in the following code is directly returned as a List <May>, which is the problem encountered by LZ.
That is to say, there is no problem with serialization and deserialization. The main problem still occurs on the WCF Assembly message.
Set the ReaderQuotas attribute, which sets the message complexity.
It seems like a DOS killer, so I thought of ReaderQuotas.
The following is an example of my attempt.
-
C # code
-
Publicbyte [] GetMays () {DataContractSerializer DCZ = new DataContractSerializer (typeof (List <May>); List <May> list = new List <May> (); for (int I = 0; I <30000; I ++) {May tmp = new May {Name = DateTime. now. toString ("yyyy-MM-dd")}; list. add (tmp);} using (MemoryStream fs = new MemoryStream () {DCZ. writeObject (fs, list); return fs. toArray ();}}-------------------
Use your method. The client must also set
NetTcpBinding. ReaderQuotas. MaxArrayLength = 2147483647;
NetTcpBinding. ReaderQuotas. MaxStringContentLength = 2147483647;
NetTcpBinding. ReaderQuotas. MaxBytesPerRead = 2147483647;
//-------------------------------
System. Diagnostics. Stopwatch myWatch = new System. Diagnostics. Stopwatch ();
MyWatch. Start ();
// TaxiInfo [] taxiInfos = PositionService. GetAllTaxiInfos ();
Byte [] sds = PositionService. GetMays ();
MyWatch. Stop ();
Console. WriteLine ("Time consumed:" + myWatch. ElapsedMilliseconds + "ms ");
MemoryStream memory = new MemoryStream (sds );
XmlDictionaryReader reader =
XmlDictionaryReader. CreateTextReader (memory, new XmlDictionaryReaderQuotas ());
DataContractSerializer ser = new DataContractSerializer (typeof (List <TaxiInfo> ));
// Deserialize the data and read it from the instance.
List <TaxiInfo> deserializedPerson =
(List <TaxiInfo>) ser. ReadObject (reader, true );
Reader. Close ();
// Console. WriteLine (deserializedPerson );
So there is no problem. 3Q ----------------------
I suspect there are other problems... I have no problem in testing 10000.
WcfLibrary:
1. contract:
-
C # code
-
[DataContract] publicclass TaxiInfo {[DataMember] publicstring PhoneNumber {get; set;} [DataMember] publicstring Others {get; set ;}} [ServiceContract] publicinterface IService1 {[OperationContract] List <TaxiInfo> GetAllTaxiInfos ();}
2. Service
-
C # code
-
[ServiceBehavior (InstanceContextMode = InstanceContextMode. single, ConcurrencyMode = ConcurrencyMode. multiple)] publicclass Service1: IService1 {privatestatic List <TaxiInfo> _ taxis = new List <TaxiInfo> (); static Service1 () {foreach (var I in Enumerable. range (1, 10000) {var taxi = new TaxiInfo {PhoneNumber = I. toString (). padLeft (12, '0')}; _ taxis. add (taxi) ;}} public List <TaxiInfo> GetAllTaxiInfos () {return _ taxis ;}}
3. Winform Host
-
C # code
-
Publicpartialclass Form1: Form {public Form1 () {InitializeComponent ();} private ServiceHost _ host; privatevoid button#click (object sender, EventArgs e) {NetTcpBinding netTcpBinding = new NetTcpBinding. none, true) {MaxBufferPoolSize = 2147483647, // 2g MaxBufferSize = 2147483647, maxcompute edmessagesize = 2147483647, SendTimeout = new TimeSpan (0, 0, 30), ReceiveTimeout = new TimeSpan (20, 0, 10), ReliableSession = {Enabled = true, InactivityTimeout = new TimeSpan (20, 0, 10) }}; try {_ host = new ServiceHost (typeof (WcfServiceLibrary1.Service1 )); serviceThrottlingBehavior throttlingBehavior = _ host. description. behaviors. find <ServiceThrottlingBehavior> (); if (throttlingBehavior = null) {throttlingBehavior = new ServiceThrottlingBehavior {maxconcurrentcils = 3000, MaxConcurrentSessions = 3000}; _ host. description. behaviors. add (throttlingBehavior);} else {throttlingBehavior. maxconcurrentcall= 3000; throttlingBehavior. maxConcurrentSessions = 3000;} // _ host. description. endpointsstring strAddress = "net. tcp: // localhost: 20000/PositionServices "; _ host. addServiceEndpoint (typeof (WcfServiceLibrary1.IService1), netTcpBinding, strAddress); _ host. open (); label1.Text = "Service is opened... ";} catch (Exception ex) {MessageBox. show (ex. message );}}}
3. WcfClient
-
C # code
-
Class Program {privatestatic WcfServiceLibrary1.IService1 PositionService = null; staticvoid Main (string [] args) {try {InitConnect (); var sw = new Stopwatch (); sw. start (); var allTaxis = PositionService. getAllTaxiInfos (); Console. writeLine (allTaxis. count); sw. stop (); Console. writeLine ("GetAllTaxiInfos Elapsed: {0} ms", sw. elapsedMilliseconds); Console. read ();} catch (Exception ex) {Console. writeLine (ex. message) ;}} staticvoid InitConnect () {NetTcpBinding netbinding = new NetTcpBinding (SecurityMode. none, true) {MaxBufferPoolSize = 2147483647, MaxBufferSize = 2147483647, maxcompute edmessagesize = 2147483647, SendTimeout = new TimeSpan (0, 0, 30), ReceiveTimeout = new TimeSpan (20, 0, 0), ReliableSession = {Enabled = true, InactivityTimeout = new TimeSpan (20, 0, 10) },}; PositionService = ChannelFactory <WcfServiceLibrary1.IService1>. createChannel (netbinding, new EndpointAddress ("net. tcp: // localhost: 20000/PositionServices "));}}
Output:
10000
GetAllTaxiInfos Elapsed: 2183 ms
-------------------------
Configure the server. It is true that, as some netizens say, the data should not be too large each time. If the data is big, it is recommended to use Asynchronous splitting into small pieces for processing. Of course, if the data is combined with the database, the paging should be done on the server.
Serialization must consume a lot of memory. ---------
It's okay to change to 100000.
100000
GetAllTaxiInfos Elapsed: 1160 ms
No problem. What's wrong with you?
Do not try OutOfMemoryException... The memory size is too small.