The WCF on A does not necessarily know that the connection has failed until you try to make use of that connection. This is a fundamental property of packet-switched networks. Unless you are using a keep-alive to detect the loss of the peer, there is no way to detect that the peer is gone/dead/unresponsive, without sending it some sort of "are you there?" message, and waiting some time for the response.
This is not a WCF oddity. This is how TCP/IP works, and it is by design. Consider two machines, A and B, who have an active TCP connection between them. There is nothing magical about the connection -- it is just an "idea" in both machines that maps a communication channel (socket) on each machine to a tuple of network addresses. In the case of TCP/IP v4, that tuple is < local-address local-port remote-address remote-port >. (It's usually stated as a 5-tuple, with the protocol "tcp" being part of the tuple.) Now, if the TCP connection is idle, i.e. neither side has anything to say, and if something terrible happens to one of the machines, or the network between them, there is no notification sent to the machines that this has happened. If B explodes, A does not receive an IP packet that says "B is gone". A can only discover that B is gone by sending B a message, and seeing if it responds. So it is perfectly reasonable for WCF to consider B to be "ready", and then for your app to call BeginOperation, and then for WCF on A to throw an exception. The WCF layer on A can only discover that the connection has failed when it tries to use the connection. Also, the .Net async design pattern specifies quite clearly that exceptions can be thrown from BOTH the BeginXxx and EndXxx methods. Both cases are completely valid means for the implementer of an asynchronous method pair to indicate that the async method has failed. On CLR 1.x and 2.x, when using async delegates, it is true that you will generally not see an exception during BeginInvoke(), unless the CLR itself is out of resources or some other terrible thing has happened. However, that is an implementation detail -- the CLR is still allowed to throw exceptions during BeginInvoke(), and your app had better be prepared to deal with them. -- arlie -----Original Message----- From: Discussion of advanced .NET topics. [mailto:[EMAIL PROTECTED] On Behalf Of Ragnvald Barth Sent: Tuesday, July 25, 2006 3:37 AM To: [email protected] Subject: Re: [ADVANCED-DOTNET] How do I detect when a connection is lost? The normal behavior is as follows: Application A calls application B, and application B returns an answer. IAsyncResult call = proxyB.BeginOperation(data, null, null); answer = proxyB.EndOperation(call); Now to the special case: Application B is killed, crashed, disconnected or somehow unable to respond. What happens then when A calls B? Let's say the call is made through an http- binding. Then EndOperation would throw an exception (that can be caught and handled in an appropriate way in application A). Now what if the binding is a NetNamedPipeBinding? Then BeginOperation throws an exception. This means that A knew that B was down so it didn't even bother to try calling B. (It also means that the code that handles an exception from EndOperation doesn't solve anything...) So, when Indigo knows in advance that B is down, there must be a way that my application code can detect it as well. And it is: If the connection between A and B is a callback channel, I can do the following: OperationContext.Current.Channel.Closing += new EventHandler (OnConnectionClosing); and thereby detect when the connection is closing! What I need to solve my problem is a way to detect that the connection is Closing also when it is not a callback channel. Can anyone help? =================================== This list is hosted by DevelopMentorR http://www.develop.com View archives and manage your subscription(s) at http://discuss.develop.com =================================== This list is hosted by DevelopMentorĀ® http://www.develop.com View archives and manage your subscription(s) at http://discuss.develop.com
