wcf channelfactory和opentimeout

时间:2012-01-21 12:54:03

标签: wcf

在客户端,我正在尝试连接到WCF,将OpenTimeout属性更改为5秒,但它无效....这就是我创建频道的方式:

NetTcpBinding bind = new NetTcpBinding(SecurityMode.None);
bind.OpenTimeout = new TimeSpan(0, 0, 5);
var channel = new ChannelFactory<IService>(bind, new EndpointAddress(myAddr)); 
channel.CreateChannel();

在此之后,我正在调用该方法但是如果服务器已经关闭,则需要21秒而不是我在OpenTimeout上更改的5,我错过了什么?

韩国社交协会

4 个答案:

答案 0 :(得分:5)

我在下一个方面解决了这个问题。它似乎是有效的。

    protected TServiceContract CreateChannel()
    {
        TServiceContract channel = factory.CreateChannel();

        var ar = ((IChannel)channel).BeginOpen( null, null );

        if( !ar.AsyncWaitHandle.WaitOne( factory.Endpoint.Binding.OpenTimeout, true ) )
        {
            throw new TimeoutException( "Service is not available" );
        }

        ((IChannel)channel).EndOpen( ar );

        return channel;
    }

答案 1 :(得分:1)

我找到的解决方案是检查wcf服务器是否已启动(在调用方法之前),具体方法如下:

Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.ReceiveTimeout = sock.SendTimeout = 500;
IAsyncResult res = sock.BeginConnect(ip, port, null, null);
bool success = res.AsyncWaitHandle.WaitOne(500, true);

答案 2 :(得分:0)

看来WCF还有其他一些不计入opentimeout的东西。看看这个帖子

http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/5f347965-13bf-4a2d-ae82-74ad38a8d7d1/

[编辑] 当我尝试使用.Net 4.0时,当wcf服务不可用时,超时发生在2秒内。 Opentimeout没有任何影响。如果wcf服务可用但没有响应原因,您可以通过在绑定上设置sendtimeout设置让客户端等待所需的时间。

答案 3 :(得分:0)

对服务上的方法的第一次调用也会打开通道。这称为自动打开,它是not recommended。相反,您应该明确地调用它:

channel.Open();
channel.RetrieveFoobars();

但是,问题仍然存在:channel.Open()不遵守绑定的OpenTimeout,而是在抛出EndpointNotFoundException之前等待大约21秒。我想这是WCF的CommunicationObject中的错误。

使用上面的代码设置((IContextChannel)channel).OperationTimeoutbind.SendTimeoutbind.OpenTimeout无济于事。 (如其他地方所建议)。

我基于this VB code确定的解决方案是使用异步方法,该方法允许您指定取消之前要等待的时间。

private void CloseChannel(ICommunicationObject channel){
  try {
    channel.Close();
  } catch {
    channel.Abort();
  }
}

private void OpenChannel(ICommunicationObject channel, TimeSpan timeout) {
  var ar = channel.BeginOpen(null, null);
  if (!ar.AsyncWaitHandle.WaitOne(timeout, true)) {
    CloseChannel(channel);
    throw new EndpointNotFoundException();
  }
  channel.EndOpen(ar);
}

您仍然必须首先将绑定的OpenTimeout设置为至少50ms,否则BeginOpen会引发TimeoutException。

bind.OpenTimeout = TimeSpan.FromMilliseconds(100d)