我创建了一个托管在普通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 out
和System.Net.WebException: Error: ConnectFailure (Connection timed out)
。
答案 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秒并将完成异常。
所以,我的意见是你不应该关心这个例外,除非它以某种方式阻止你的申请。