所以我正在编写一个调用WCF服务的控制台应用程序(通过nettcpbinding) - 并且企业希望能够指定一个值作为超时值。我最初尝试操作超时,但似乎被忽略了 - 所以我尝试了一堆其他值。其中一个作品(或组合):)
我希望如果它超时,我仍然可以关闭通道 - 但是如果我将结束放在finally块中,那么它会再坐一会儿,直到它超时(而我设置的超时值以秒为单位)。我正在通过在服务器端代码中添加延迟进行测试 - 模拟它需要一段时间。
我可以移动靠近第一个试块,但我担心我会打开通道。然后它会更快地向用户报告超时错误。或者我需要实现线程化吗?
public static String ExecuteSearch(List<KeyValuePair<string, string>> paramItems)
{
var context = GetAdminContext();
var parsedParameters = ParseParameters((paramItems));
//TODO: Figure out how to implement timeout - & workout if port number will be passed in??
IPartyProfile partyProfile = null;
long start = System.Environment.TickCount;
using (ChannelFactory<IPartyController> factory = new ChannelFactory<IPartyController>("IPartyControllerEndpoint"))
{
EndpointAddress address = new EndpointAddress(String.Format("net.tcp://{0}/ServiceInterface/PartyController.svc", parsedParameters.HostName));
IPartyController proxy = factory.CreateChannel(address);
if (proxy != null)
{
var timeoutTimeSpan = new TimeSpan(0, 0, parsedParameters.TimeOut);
((IContextChannel)proxy).OperationTimeout = timeoutTimeSpan;
factory.Endpoint.Binding.SendTimeout = timeoutTimeSpan;
factory.Endpoint.Binding.ReceiveTimeout = timeoutTimeSpan;
factory.Endpoint.Binding.OpenTimeout = timeoutTimeSpan;
factory.Endpoint.Binding.CloseTimeout = timeoutTimeSpan;
try
{
// TODO: potentially call something more complex
partyProfile = proxy.GetLatestPartyProfile(context, parsedParameters.PartyId);
}
catch (EndpointNotFoundException ex)
{
throw new Exception(STATUS_UNKNOWN + ": Endpoint specified not responding", ex);
}
catch (TimeoutException ex)
{
throw new Exception(STATUS_UNKNOWN + ": Timeout exceeded", ex);
}
finally
{
try
{
((IClientChannel)proxy).Close();
}
catch (Exception)
{
}
}
}
}
long stop = System.Environment.TickCount;
long elapsed = (stop - start) / 1000; // in seconds
return SetResultMessage(elapsed, partyProfile, parsedParameters);
}
编辑 - 我想我可以使用factory.Abort()来更快地结束它。 (我把它放在上面代码中的Close处。)
答案 0 :(得分:1)
根据您的说明,SendTimeout
正是您要调整的值(另请参阅this question on various timeouts)。默认情况下它是1分钟,但是如果你把它改成更少的东西(例如5秒),调用proxy.GetLatestPartyProfile
确实应该在5秒后抛出一个TimeoutException(假设服务调用花费的时间超过响应时间)。
在您目前发布的代码中,我至少可以看到一个可能导致您出现问题的事情:您正在 之后设置工厂的超时值已经创建了代理。重新排序相关语句并重试。像这样:
using (ChannelFactory<IPartyController> factory = new ChannelFactory<IPartyController>("IPartyControllerEndpoint"))
{
var timeoutTimeSpan = new TimeSpan(0, 0, parsedParameters.TimeOut);
factory.Endpoint.Binding.SendTimeout = timeoutTimeSpan;
EndpointAddress address = new EndpointAddress(String.Format("net.tcp://{0}/ServiceInterface/PartyController.svc", parsedParameters.HostName));
IPartyController proxy = factory.CreateChannel(address);
if (proxy != null)
{
try
{
// TODO: potentially call something more complex
partyProfile = proxy.GetLatestPartyProfile(context, parsedParameters.PartyId);
}
// etc.
注意:我不完全确定您当前的重载voor CreateChannel
用于绑定。似乎有理由使用您之前设置的绑定,但如果您仍然遇到问题,可以使用CreateChannel(Binding, EndpointAddress)
重载进行试验。