学会WCF之试错法——超时
Posted 甜橙很酸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学会WCF之试错法——超时相关的知识,希望对你有一定的参考价值。
服务契约
[ServiceContract] public interface IService { [OperationContract] string GetData(int value); [OperationContract] string GetString(string value); [OperationContract] void Upload(Request request); } [MessageContract] public class Request { [MessageHeader(MustUnderstand = true)] public string FileName { get; set; } [MessageBodyMember(Order = 1)] public Stream Content {get;set;} }
服务
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Reentrant)] public class Service : IService { public string GetData(int value) { //Thread.Sleep(120000); return string.Format("You entered: {0}", value); } public string GetString(string value) { //Thread.Sleep(120000); return string.Format("You entered: {0}", value); } public void Upload(Request request) { try { StreamReader sr = new StreamReader(request.Content, Encoding.GetEncoding("GB2312")); StreamWriter sw = new StreamWriter("E:\\\\" + request.FileName + ".txt", false, Encoding.GetEncoding("GB2312")); while (!sr.EndOfStream) { sw.WriteLine(sr.ReadLine()); //Thread.Sleep(5000); } sr.Close(); sw.Close(); } catch (Exception ex) { } } }
服务配置
<system.serviceModel> <services> <service name="WCF_Find_Error_Lib.Service"> <endpoint address="" binding="basicHttpBinding" contract="WCF_Find_Error_Lib.IService"> <identity> <dns value="localhost" /> </identity> </endpoint> <host> <baseAddresses> <add baseAddress="http://localhost/S" /> </baseAddresses> </host> </service> </services> <behaviors> <serviceBehaviors> <behavior> <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/> <serviceDebug includeExceptionDetailInFaults="False" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
客户端代理
public class ServiceProxy { public string GetData(int value) { string ret = null; ServiceClient client = null; try { client = new ServiceClient(); ret = client.GetData(value); client.Close(); } catch { if (client != null) { client.Abort(); } throw; } return ret; } public string GetString(string value) { string ret = null; ServiceClient client = null; try { client = new ServiceClient(); ret = client.GetString(value); client.Close(); } catch { if (client != null) { client.Abort(); } throw; } return ret; } public void Upload(Request request) { ServiceClient client = null; try { client = new ServiceClient(); client.Upload(request); client.Close(); } catch { if (client != null) { client.Abort(); } throw; } } } [ServiceContractAttribute(ConfigurationName = "IService")] public interface IService { [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IService/GetData", ReplyAction = "http://tempuri.org/IService/GetDataResponse")] string GetData(int value); [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IService/GetString", ReplyAction = "http://tempuri.org/IService/GetStringResponse")] string GetString(string value); [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IService/Upload", ReplyAction = "http://tempuri.org/IService/UploadResponse")] void Upload(Request request); } [MessageContract] public class Request { [MessageHeader(MustUnderstand = true)] public string FileName { get; set; } [MessageBodyMember(Order = 1)] public Stream Content { get; set; } } [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Reentrant)] public class ServiceClient : System.ServiceModel.ClientBase<IService>, IService { public ServiceClient() { } public string GetData(int value) { return base.Channel.GetData(value); } public string GetString(string value) { return base.Channel.GetString(value); } public void Upload(Request request) { base.Channel.Upload(request); } }
客户端配置
<system.serviceModel> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IService" /> </basicHttpBinding> </bindings> <client> <endpoint address="http://localhost/S" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService" contract="IService" name="BasicHttpBinding_IService" /> </client> </system.serviceModel>
1 客户端调用超时
运行客户端,执行调用
ServiceProxy proxy = new ServiceProxy();
string s = proxy.GetData(1);
通过配置sendTimeout参数设定超时时间,超时时间默认为1分钟,上述配置中采用了默认超时时间。
Message
请求通道在等待 00:00:59.9469970 以后答复时超时。增加传递给请求调用的超时值,或者增加绑定上的 SendTimeout 值。分配给此操作的时间可能已经是更长超时的一部分。
Stacktrace:
Server stack trace:
在 System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
在 System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
在 System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
在 System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
在 System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
在 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
在 Client.IService.GetData(Int32 value)
在 Client.ServiceClient.GetData(Int32 value) 位置 e:\\projgxz_myself\\WCF_Find_Error\\Client\\ServiceProxy.cs:行号 52
在 Client.ServiceProxy.GetData(Int32 value) 位置 e:\\projgxz_myself\\WCF_Find_Error\\Client\\ServiceProxy.cs:行号 19
在 Client.Program.Main(String[] args) 位置 e:\\projgxz_myself\\WCF_Find_Error\\Client\\Program.cs:行号 17
增大客户端调用超时时间,可解决超时问题
例如,超时时间设置为10分钟,满足此次调用需求。
<system.serviceModel> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IService" sendTimeout="00:10:00"/> </basicHttpBinding> </bindings> <client> <endpoint address="http://localhost/S" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService" contract="IService" name="BasicHttpBinding_IService" /> </client> </system.serviceModel>
2 非活动状态的最大时间间隔
通过配置receiveTimeout设定时间间隔,默认值为 10 分钟。
服务实例化模式改为为会话模式:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Reentrant)]
服务端配置
<netTcpBinding> <binding name="NetTcpBinding_IService" maxBufferSize="270000" maxReceivedMessageSize="270000" transferMode="Buffered" receiveTimeout="00:00:10"> <readerQuotas maxStringContentLength="240000"/> <reliableSession enabled="true" inactivityTimeout="00:00:10"/> </binding> </netTcpBinding>
客户端配置
<netTcpBinding> <binding name="NetTcpBinding_IService" sendTimeout="00:00:10" maxBufferSize="2700000" maxReceivedMessageSize="2700000" transferMode="Buffered" > <readerQuotas maxStringContentLength="240000"/> </binding> </netTcpBinding>
客户端调用
using (ServiceClient client = new ServiceClient()) { StreamReader sr = new StreamReader("D:\\\\CSBMTEMP.txt", Encoding.Default); string str = sr.ReadToEnd(); sr.Close(); client.GetString(str); Thread.Sleep(100000); client.GetString(str); }
运行客户端程序,成功捕获异常
上述异常中给出的错误信息并未指出具体的异常原因,所以从中很难推测是由于超时时间设置问题。遇到此类问题只能根据经验逐项排查,当然这是很浪费时间的,尤其是对于复杂的程序,更是如此。
-----------------------------------------------------------------------------------------
转载与引用请注明出处。
时间仓促,水平有限,如有不当之处,欢迎指正。
以上是关于学会WCF之试错法——超时的主要内容,如果未能解决你的问题,请参考以下文章