WCF 传输大数据的问题。

a12321321321312321 2011-12-29 07:59:07



// ------服务端WCF实现代码 CSDN 代码折叠的功能都没,fuck。--------------------------------------
NetTcpBinding netTcpBinding = new NetTcpBinding(SecurityMode.None, true)
{
MaxBufferPoolSize = 2147483647,//2g
MaxBufferSize = 2147483647,
MaxReceivedMessageSize = 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(Service.PositionService));
ServiceThrottlingBehavior throttlingBehavior =
_host.Description.Behaviors.Find<ServiceThrottlingBehavior>();
if (throttlingBehavior == null)
{
throttlingBehavior = new ServiceThrottlingBehavior { MaxConcurrentCalls = 3000, MaxConcurrentSessions = 3000 };
_host.Description.Behaviors.Add(throttlingBehavior);
}
else
{
throttlingBehavior.MaxConcurrentCalls = 3000;
throttlingBehavior.MaxConcurrentSessions = 3000;
}
//_host.Description.Endpoints

string strAddress = string.Format(@"net.tcp://{0}:" + Common.ConstParameters.WcfPort + "/PositionServices", _serverIp);
_host.AddServiceEndpoint(typeof(Service.IPositionService), netTcpBinding, strAddress);
_host.Open();

//-------客户端WCF初始化代码-------------------------------------------------------------------
private int InitWcfService(string ip)
{
try
{
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 = true, InactivityTimeout = new TimeSpan(20, 0, 10) },
};
PositionService = ChannelFactory<IPositionService>.CreateChannel
(netbinding, new EndpointAddress("net.tcp://" + ip + ":" + Common.ConstParameters.WcfPort + "/PositionServices"));
}
catch (Exception ex)
{
return 0;
}
return 1;

}

//--------服务端接口实现代码------------------------------------------------------------------------
private void MainForm_Load(object sender, EventArgs e)
{
InitServerOperation();
//!--For Test
for (int i = 0; i < 2800; i++)
{
TaxiInfo taxiInfo = new TaxiInfo
{
PhoneNumber = i.ToString().PadLeft(12, '0')
};
TaxiList.Add(i.ToString(), taxiInfo);
}
}
//-------------
public List<Model.TaxiInfo> GetAllTaxiInfos()
{
lock (TaxiList.SyncRoot)
{
List<TaxiInfo> taxiInfos = new List<TaxiInfo>();
foreach (TaxiInfo taxiInfo in TaxiList.Values)
{
taxiInfos.Add(taxiInfo);
}
return taxiInfos;
}

}
//---客户端调用测试方法------------------------------------------------------------------------------
private void button1_Click(object sender, EventArgs e)
{

System.Diagnostics.Stopwatch myWatch = new System.Diagnostics.Stopwatch();
myWatch.Start();
List<TaxiInfo> taxiInfos = PositionService.GetAllTaxiInfos();
myWatch.Stop();
Console.WriteLine("耗时:" + myWatch.ElapsedMilliseconds + "ms");
}



测试发现i<=2700的时候正常传输,耗时100毫秒左右。。。。。大于2700的时候不正常。
for (int i = 0; i < 2800; i++)
...全文
2258 50 打赏 收藏 转发到动态 举报
写回复
用AI写文章
50 条回复
切换为时间正序
请发表友善的回复…
发表回复
yzy85 2012-01-03
  • 打赏
  • 举报
回复
[Quote=引用 46 楼 qldsrx 的回复:]

怎么结贴了?帮你找出问题并解决了,回来一看,帖子结了。
[/Quote]

结贴了,怎么就不说出你的解决方案了,起码让我们这些后来者学习下啊?
广州接入 2012-01-03
  • 打赏
  • 举报
回复
类似的问题我在整WCF Ria时也遇到过,服务端配置一下就可以。确实如有网友说的,每次数据不要太大,建议如果数据大的话用异步分割成小块去处理,当然如果是结合数据库的话,分页最好是在服务端做。
序列化肯定很耗内存的.
siaosa_ding 2012-01-01
  • 打赏
  • 举报
回复
WCF不能一次性传输太大的数据,
如果网络流量不好,延时的话数据越小越好,如果传输的时间太长了,也会发生这样的错误。
qldsrx 2011-12-31
  • 打赏
  • 举报
回复
楼上贴了那么多代码,不如直接把整个测试项目上传到网盘,然后下载调试,这样更利于发现问题(也许是配置文件问题,也许是代码问题)。
qldsrx 2011-12-31
  • 打赏
  • 举报
回复
怎么结贴了?帮你找出问题并解决了,回来一看,帖子结了。
机器人 2011-12-30
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 sunzongbao2007 的回复:]

引用 19 楼 fangxinggood 的回复:

我觉得还是配置大小限制的事,都用byte[]传?wcf岂不是太弱了。。。

另外,你的2800条数据也不是很大呀。

但你描述的问题最后是超时这个错误没遇见过。
你配置一下下面的内容再看看。

<behavior name="NewBehavior">
<dataContractSerializer maxItemsInO……
[/Quote]

恩,是这个意思。但lz说是timeout,所以我也拿不准是不是这个原因。
铜臂阿铁木 2011-12-30
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 fangxinggood 的回复:]

我觉得还是配置大小限制的事,都用byte[]传?wcf岂不是太弱了。。。

另外,你的2800条数据也不是很大呀。

但你描述的问题最后是超时这个错误没遇见过。
你配置一下下面的内容再看看。

<behavior name="NewBehavior">
<dataContractSerializer maxItemsInObjectGraph="65536000" />……
[/Quote]
是啊byte[]各种弱。。。果断试试这个方法。
binding里面找了半天这个属性原来在behavior里,自定义序列化方法的时候用了那么多的behavior配置还是没法一下想到这,还是理解不够,学艺不精。
有个印象ObjectGraph的数量不是List<Item> items里面Item的数量,而是items里面所有引用的对象实例数量。
机器人 2011-12-30
  • 打赏
  • 举报
回复
我觉得还是配置大小限制的事,都用byte[]传?wcf岂不是太弱了。。。

另外,你的2800条数据也不是很大呀。

但你描述的问题最后是超时这个错误没遇见过。
你配置一下下面的内容再看看。

<behavior name="NewBehavior">
<dataContractSerializer maxItemsInObjectGraph="65536000" />
</behavior>

在ServiceEndpoint 里加上这个behavior 再看看。
http://blog.csdn.net/fangxinggood/article/details/6031072
铜臂阿铁木 2011-12-30
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 f800051235 的回复:]

引用 16 楼 sunzongbao2007 的回复:

难道是WCF防DOS防的太死了?依然不懂,依然等大神。

那我就晚点结贴吧。万分感谢。。
[/Quote]

嗯,我也想要答案,因为这个问题我也遇见了。
a12321321321312321 2011-12-30
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 sunzongbao2007 的回复:]

难道是WCF防DOS防的太死了?依然不懂,依然等大神。
[/Quote]
那我就晚点结贴吧。万分感谢。。
铜臂阿铁木 2011-12-30
  • 打赏
  • 举报
回复
难道是WCF防DOS防的太死了?依然不懂,依然等大神。
铜臂阿铁木 2011-12-30
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 f800051235 的回复:]

引用 13 楼 sunzongbao2007 的回复:

我刚刚试了下,使用WCF的默认DataContractSerializer手动去序列化成byte[],然后接收后再手动去反序列化
。。。。


万分感谢,用你这个方法搞定。客户端还要设置下
netTcpBinding.ReaderQuotas.MaxArrayLength = 2147483647;
……
[/Quote]

诶,也是治标不治本啊。还是有什么底层的没搞清楚。
a12321321321312321 2011-12-30
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 sunzongbao2007 的回复:]

我刚刚试了下,使用WCF的默认DataContractSerializer手动去序列化成byte[],然后接收后再手动去反序列化
。。。。
[/Quote]

万分感谢,用你这个方法搞定。客户端还要设置下
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("耗时:" + 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);

这样就没问题了。3Q
a12321321321312321 2011-12-30
  • 打赏
  • 举报
回复
[Quote=引用 43 楼 fangxinggood 的回复:]

这... 不解了。看看有什么东西限速嘛?除了.net 其他看看能关都关了。
[/Quote]

额。试的没用。。我用上面那位兄弟的public byte[] GetMays()的方法发现获得的数据有8M这么大,不知道有没有影响。。 麻烦你帮我看这么长时间了。谢了。。
机器人 2011-12-30
  • 打赏
  • 举报
回复
这... 不解了。看看有什么东西限速嘛?除了.net 其他看看能关都关了。

a12321321321312321 2011-12-30
  • 打赏
  • 举报
回复
[Quote=引用 41 楼 fangxinggood 的回复:]

你用 release 编译出 winform.exe 和 console.exe

不要开 vs,再跑一下。如果能过,那么很大可能性是内存不足啊。
[/Quote]
release 也不行。。4G内存应该不会不足吧?
机器人 2011-12-30
  • 打赏
  • 举报
回复
你用 release 编译出 winform.exe 和 console.exe

不要开 vs,再跑一下。如果能过,那么很大可能性是内存不足啊。
a12321321321312321 2011-12-30
  • 打赏
  • 举报
回复
[Quote=引用 39 楼 fangxinggood 的回复:]

引用 38 楼 f800051235 的回复:

引用 37 楼 fangxinggood 的回复:

写错了每个字段100个字符。

copy 了,你13楼的代码,新建的项目,超过30000就不行了。

运行环境 .NET 4.0 ,测试代码工程 http://115.com/file/bew3ytsu#Test.rar
C# code

public List<Tax……
[/Quote]

没什么错误。。等30S没响应。。然后报 超时。

发送到 net.tcp://localhost:20000/PositionServices 的请求操作在配置的超时(00:00:30)内未收到回复。分配给此操作的时间可能已经是更长超时的一部分。这可能由于服务仍在处理操作或服务无法发送回复消息。请考虑增加操作超时(将通道/代理转换为 IContextChannel 并设置 OperationTimeout 属性)并确保服务能够连接到客户端。



static Service1()
{
for (int i = 0; i < 25000; i++)
{
var taxi = new TaxiInfo { PhoneNumber = i.ToString().PadLeft(12, '0') };
_taxis.Add(taxi);
}
}
机器人 2011-12-30
  • 打赏
  • 举报
回复
[Quote=引用 38 楼 f800051235 的回复:]

引用 37 楼 fangxinggood 的回复:

写错了每个字段100个字符。

copy 了,你13楼的代码,新建的项目,超过30000就不行了。

运行环境 .NET 4.0 ,测试代码工程 http://115.com/file/bew3ytsu#Test.rar
C# code

public List<TaxiInfo> GetAllTaxiInf……
[/Quote]

还是一样,改到 100000 也没错

100000
GetAllTaxiInfos Elapsed:1160ms


没问题啊,你出什么错误?

OutOfMemoryException 就不要试了。。。内存太小了。
a12321321321312321 2011-12-30
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 fangxinggood 的回复:]

写错了每个字段100个字符。
[/Quote]
copy 了,你13楼的代码,新建的项目,超过30000就不行了。

运行环境 .NET 4.0 ,测试代码工程 http://115.com/file/bew3ytsu#Test.rar

public List<TaxiInfo> GetAllTaxiInfos()
{
for (int i = 0; i < 30000; i++)
{
var taxi = new TaxiInfo { PhoneNumber = i.ToString().PadLeft(12, '0') };
_taxis.Add(taxi);
}
return _taxis;
}
加载更多回复(25)

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧