ServiceChannel通过tcp cannel传递大数组时出现Faulted状态异常
这是我用来启动服务器的代码:
ServiceHost svh = new ServiceHost(typeof(MyService));
var tcpbinding = new NetTcpBinding();
//remove limits on the max array size
tcpbinding.MaxReceivedMessageSize = 2147483647;
tcpbinding.ReaderQuotas.MaxArrayLength = 2147483647;
tcpbinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
tcpbinding.ReaderQuotas.MaxStringContentLength = 2147483647;
tcpbinding.ReaderQuotas.MaxDepth = 2147483647;
svh.AddServiceEndpoint(typeof(IMyService), tcpbinding, location);
// Check to see if the service host already has a ServiceMetadataBehavior
ServiceMetadataBehavior smb = svh.Description.Behaviors.Find<ServiceMetadataBehavior>();
// If not, add one
if (smb == null)
smb = new ServiceMetadataBehavior();
//smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
svh.Description.Behaviors.Add(smb);
// Add MEX endpoint
svh.AddServiceEndpoint(
ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexTcpBinding(),
location+"/mex"
);
svh.Open();
这是修改后的客户端 app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IMyService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:8666/myservice" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IMyService"
contract="VMyService.IMyService" name="NetTcpBinding_IMyService">
<identity>
<userPrincipalName value="badasscomputing\menkaur" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
这是测试客户端代码:
var r=client.GetResult(26);
其中 GetResult 返回对象数组。当数组很小时,它可以正常工作,没有任何问题,但是当我尝试提取包含 3 126 309 个项目(字符串,在本例中代表网页 url)的字符串数组时,我收到以下异常:
System.ServiceModel.CommunicationObjectFaultedException was unhandled
Message=The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
Source=mscorlib
StackTrace:
Server stack trace:
at System.ServiceModel.Channels.CommunicationObject.ThrowIfFaulted()
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at apiDemo.NS.IMyService.GetResult(UInt64 taskId)
at apiDemo.NS.MyServiceClient.GetResult(UInt64 taskId) in D:\Users\menkaur\Documents\Visual Studio 2010\Projects\myProject\apiDemo\apiDemo\Service References\MyService\Reference.cs:line 1456
at apiDemo.Program.Main(String[] args) in D:\Users\menkaur\Documents\Visual Studio 2010\Projects\myProject\apiDemo\apiDemo\Program.cs:line 190
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
看起来这来自于正在传输的大数组大小,但我删除了对我能找到的数组大小的任何限制。
有什么我错过的事情还是来自其他方向?
Here's the code I'm using to start the server:
ServiceHost svh = new ServiceHost(typeof(MyService));
var tcpbinding = new NetTcpBinding();
//remove limits on the max array size
tcpbinding.MaxReceivedMessageSize = 2147483647;
tcpbinding.ReaderQuotas.MaxArrayLength = 2147483647;
tcpbinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
tcpbinding.ReaderQuotas.MaxStringContentLength = 2147483647;
tcpbinding.ReaderQuotas.MaxDepth = 2147483647;
svh.AddServiceEndpoint(typeof(IMyService), tcpbinding, location);
// Check to see if the service host already has a ServiceMetadataBehavior
ServiceMetadataBehavior smb = svh.Description.Behaviors.Find<ServiceMetadataBehavior>();
// If not, add one
if (smb == null)
smb = new ServiceMetadataBehavior();
//smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
svh.Description.Behaviors.Add(smb);
// Add MEX endpoint
svh.AddServiceEndpoint(
ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexTcpBinding(),
location+"/mex"
);
svh.Open();
here's the modified client app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IMyService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:8666/myservice" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IMyService"
contract="VMyService.IMyService" name="NetTcpBinding_IMyService">
<identity>
<userPrincipalName value="badasscomputing\menkaur" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
here's the test client code:
var r=client.GetResult(26);
where GetResult returns object array. When the array is small, it works without any problems, but when I'm trying to pull through a string array of 3 126 309 items (strings, in this case representing web page urls), I'm getting following exception:
System.ServiceModel.CommunicationObjectFaultedException was unhandled
Message=The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
Source=mscorlib
StackTrace:
Server stack trace:
at System.ServiceModel.Channels.CommunicationObject.ThrowIfFaulted()
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at apiDemo.NS.IMyService.GetResult(UInt64 taskId)
at apiDemo.NS.MyServiceClient.GetResult(UInt64 taskId) in D:\Users\menkaur\Documents\Visual Studio 2010\Projects\myProject\apiDemo\apiDemo\Service References\MyService\Reference.cs:line 1456
at apiDemo.Program.Main(String[] args) in D:\Users\menkaur\Documents\Visual Studio 2010\Projects\myProject\apiDemo\apiDemo\Program.cs:line 190
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
It looks like this comes from a large array size being transmitted, but I removed any limits to the array size I could find.
Is there anything that I have missed or does this come from an other direction?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您需要更改 MaxItemsInObjectGraph 。抛开事实不谈,正如 Henk Holterman 指出的那样,传递 300 万个字符串可能不是最好的想法。
I think you'll need to change MaxItemsInObjectGraph. The fact aside that as Henk Holterman points out that passing 3 million strings is probably not the best of ideas.