我的问题与 WCF 不时抛出的 System.TimeoutException 有关:
System.TimeoutException:打开操作未在分配的 00:00:00 超时内完成。分配给此操作的时间可能是较长超时的一部分。---> System.TimeoutException:在 00:00:00 后打开超时,同时建立到 net.tcp://192.168.1.100:50000/TabletSvc/ 的传输会话。分配给此操作的时间可能是较长超时的一部分。---> System.TimeoutException:通过 net.tcp://192.168.1.100:50000/TabletSvc/ 连接到 00:00:00 后超时。对 1 个可用地址中的 0 个进行了连接尝试 ()。检查您的通道的 RemoteAddress 并验证此端点的 DNS 记录是否对应于有效的 IP 地址。分配给此操作的时间可能是较长超时的一部分。
随机行为的可能原因是什么?
WCF 服务托管在 Windows XP SP2 上运行的 .NET 应用程序中。该应用程序为托管在不同机器上的相同服务创建客户端代理。一个重要方面是该服务正在使用可靠会话和服务限制。机器通过 WiFi 连接进行通信。
客户端和服务位于同一应用程序内的不同线程上。从这个角度来看,它们并不相互依赖。不应该有锁定。
我使用 ping 检查了机器之间的 WiFi 连接,它似乎很好。下一步将是安装一个网络监视器,但由于它们是生产机器,它可能不会很快发生。
我考虑将 maxConcurrentSessions 和 maxConcurrentInstances 都增加到 50,但没有时间测试它。这是基于这样的想法,即应用程序可能正在耗尽资源或达到影响托管服务的限制。
正如我所说,客户端代理有时无法打开连接。一分钟后的第二次尝试通常会成功。
这是客户端和服务配置:
<system.serviceModel>
<client>
<endpoint name="TabletSvcEndpoint" address="net.tcp://localhost:50000/TabletSvc/" binding="netTcpBinding" bindingConfiguration="TabletSvcBinding" contract="ITabletSvc">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
<services>
<service behaviorConfiguration="TabletSvcBehavior" name="TabletSvc">
<endpoint name="TabletSvcEndpoint" address="" binding="netTcpBinding" bindingConfiguration="TabletSvcBinding" contract="ITabletSvc">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:50000/TabletSvc/" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="TabletSvcBinding" receiveTimeout="00:30:00" sendTimeout="00:00:30" closeTimeout="00:00:05" openTimeout="00:00:05" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="6553600" maxConnections="10" maxReceivedMessageSize="6553600">
<readerQuotas maxDepth="32" maxStringContentLength="819200" maxArrayLength="163840" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession inactivityTimeout="00:01:00" ordered="true" enabled="true" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="TabletSvcBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentSessions="10" maxConcurrentInstances="10" maxConcurrentCalls="100" />
</behavior>
</serviceBehaviors>
</behaviors>
<diagnostics performanceCounters="Off" wmiProviderEnabled="False" >
<messageLogging maxMessagesToLog="250" logEntireMessage="true" logMessagesAtServiceLevel="true" logMalformedMessages="true" logMessagesAtTransportLevel="true" />
</diagnostics>
</system.serviceModel>
这是异常的堆栈跟踪:
10:20:18.3125 ClientChannel: Opening
10:20:48.8437 ClientChannel: Faulted
10:20:48.8593 Error: System.TimeoutException: The open operation did not complete within the allotted timeout of 00:00:00. The time allotted to this operation may have been a portion of a longer timeout. ---> System.TimeoutException: Open timed out after 00:00:00 while establishing a transport session to net.tcp://192.168.1.100:50000/TabletSvc/. The time allotted to this operation may have been a portion of a longer timeout. ---> System.TimeoutException: Connecting to via net.tcp://192.168.1.100:50000/TabletSvc/ timed out after 00:00:00. Connection attempts were made to 0 of 1 available addresses (). Check the RemoteAddress of your channel and verify that the DNS records for this endpoint correspond to valid IP Addresses. The time allotted to this operation may have been a portion of a longer timeout.
at System.ServiceModel.Channels.SocketConnectionInitiator.CreateTimeoutException(Uri uri, TimeSpan timeout, IPAddress[] addresses, Int32 invalidAddressCount, SocketException innerException)
at System.ServiceModel.Channels.SocketConnectionInitiator.Connect(Uri uri, TimeSpan timeout)
at System.ServiceModel.Channels.BufferedConnectionInitiator.Connect(Uri uri, TimeSpan timeout)
at System.ServiceModel.Channels.TracingConnectionInitiator.Connect(Uri uri, TimeSpan timeout)
at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
--- End of inner exception stack trace ---
at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
--- End of inner exception stack trace ---
Server stack trace:
at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ReliableChannelBinder`1.ChannelSynchronizer.SyncWaiter.TryGetChannel()
at System.ServiceModel.Channels.ReliableChannelBinder`1.ChannelSynchronizer.SyncWaiter.TryWait(TChannel& channel)
at System.ServiceModel.Channels.ReliableChannelBinder`1.ChannelSynchronizer.TryGetChannel(Boolean canGetChannel, Boolean canCauseFault, TimeSpan timeout, MaskingMode maskingMode, TChannel& channel)
at System.ServiceModel.Channels.ReliableChannelBinder`1.Send(Message message, TimeSpan timeout, MaskingMode maskingMode)
at System.ServiceModel.Channels.SendReceiveReliableRequestor.OnRequest(Message request, TimeSpan timeout, Boolean last)
at System.ServiceModel.Channels.ReliableRequestor.Request(TimeSpan timeout)
at System.ServiceModel.Channels.ClientReliableSession.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ClientReliableDuplexSessionChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
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)