关于Timouts和Exceptions的奇怪的WCF行为

时间:2017-03-14 07:51:32

标签: c# wcf xamarin.forms

我创建了一个托管在普通Windows服务中的WCF服务。此服务部署到客户并在其服务器上进行设置。因此(afaik)我需要动态建立WCF代理,不能依赖VS或Silverlight工具创建的某些预构建代理。在这种情况下,客户端是使用Xamarin.Forms构建的移动应用程序 用于创建"频道":

的代码
public void Init(int timeout = 15)
{
    ea = new EndpointAddress(string.Format("http://{0}:{1}/{2}", _settingsService.ConnectionIP, _settingsService.ConnectionPort, _settingsService.ConnectionEndpoint));
    bhttpb = new BasicHttpBinding(BasicHttpSecurityMode.None);
    bhttpb.SendTimeout = TimeSpan.FromSeconds(timeout);

    cfIMMC = new ChannelFactory<IMaintMobileContract>(bhttpb, ea);
    cfIMMC.Opened += cfIMMC_Opened;
    cfIMMC.Faulted += cfIMMC_Faulted;
    cfIMMC.Closed += cfIMMC_Closed;

    immc = cfIMMC.CreateChannel(ea);
    immc.Ping(); // This function is defined by me in the Contract. It only returns true, if the server can be reached.
}

到目前为止,如果服务正在运行,一切正常,但应用程序必须运行&#34;离线&#34;然后它变得怪异。
当建立连接时,没有EndpointException或任何东西,并且当一个函数被调用时,它就坐在那里等待超时到达。
获取WCF服务实际存在与否的信息真的很不错。我有多达几分钟的函数调用,当WCF服务器根本不存在时,应用程序等待那么久会是致命的。我怎样才能做到这一点?

更新
现在它甚至变得怪异了。现在,aprox。 Ping()失败后30秒,我无处可获得System.Net.Sockets.SocketException: Connection timed outSystem.Net.WebException: Error: ConnectFailure (Connection timed out)

更新2: 这里是CallStack的图片: enter image description here

1 个答案:

答案 0 :(得分:1)

如果您需要有关服务是否存在的快速反馈,请设置其他端点(单独的合同仅包含Ping方法)并为其设置较小的超时。 重要的是将发送/接收超时设置为较小的值 - 如果服务不可用,这将确保Ping方法返回/快速抛出。

据我所知,在你调用其中一个方法之前,WCF没有打开通道(==没有连接到服务器) - 这就是为什么在调用Ping之前没有异常的原因。

关于30秒后的异常。你在哪里看到的?我的意思是Visual Studio在那里打破或者您的应用程序是否因未处理的异常而失败?我问它是因为我在Xamarin / Mono代码中看到了这个:

initConn = new WaitCallback (state => {
    try {
        InitConnection (state);
    } catch {}
});

这意味着即使在30秒后抛出此异常 - 它也会被吞噬。真正发生的是当发送请求时(即,当您调用Ping()时)运行时尝试在后台打开连接(您的调用堆栈确认),并且30秒是默认的Windows超时连接。如果WCF的超时设置较低(如您的情况),则WCF将提前失败,但连接尝试将持续30秒并将完成异常。

所以,我的意见是你不应该关心这个例外,除非它以某种方式阻止你的申请。