|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Async TCPListener (FW 2.0): Quit listeningsurprisingly, I didn't find any satisfying answer to the following question: Situation: I use the TCPListener's BeginAcceptTcpClient method. In the callback procedure I call EndAcceptTcpClient. To stop listening, the listener's stop method is to be called. PRB: If I call Stop, the callback procedure is called even though no connection has been made. This leads to an ObjectDisposedException when calling EndAcceptTcpClient. Questions: - Why is the callback called at all? There is no incoming connection. - What is the correct way to handle the problem? Am I to call EndAcceptTcpClient in any case and catch the ObjectDisposedException? Or should I better query listener.Pending and call EndAcceptTcpClient only if it returns True? If it is False, what happens due to the missing call to EndAcceptTcpClient? I thought Begin* and End* are to be used in pairs. - I actually don't want to "End" listening, so why call End* even though I want to keep on accepting more clients? - The FW's async model is not very comprehensive. Why is there not a simple Event from the listener (maybe in another thread)? Armin Armin Zingler wrote:
> [...] The callback simply notifies you that the operation has completed. It's > PRB: > If I call Stop, the callback procedure is called even though no connection > has been made. This leads to an ObjectDisposedException when calling > EndAcceptTcpClient. > > Questions: > - Why is the callback called at all? There is no incoming connection. not restricted to successful completions. > - What is the correct way to handle the problem? Am I to call Yes.> EndAcceptTcpClient in any case and catch the ObjectDisposedException? > Or They should be, and that's why your callback is called and why you > should I better query listener.Pending and call EndAcceptTcpClient only if > it returns True? If it is False, what happens due to the missing call to > EndAcceptTcpClient? I thought Begin* and End* are to be used in pairs. should still call EndAcceptTcpClient. You should think of the Begin/End methods as two halves of the single synchronous method. The single synchronous method doesn't complete halfway; if there's an error, it still does the entire thing. So, if you call AcceptTcpClient and then close the socket from a different thread, AcceptTcpClient will throw an exception. Likewise, since calling BeginAcceptTcpClient is like the calling AcceptTcpClient, while EndAcceptTcpClient is like having your code go back to that call and allowing it to complete, you should expect EndAcceptTcpClient to do whatever AcceptTcpClient might have done. Including throwing an exception when you close the socket. > - I actually don't want to "End" listening, so why call End* even though I You need to call End because you called Begin.> want to keep on accepting more clients? > - The FW's async model is not very comprehensive. Why is there not a simple Because that's not the design pattern that was chosen for TcpClient. > Event from the listener (maybe in another thread)? You may want to review the MSDN documentation regarding asynchronous programming in .NET: http://msdn2.microsoft.com/en-us/library/ms228969.aspx IMHO, that section of the docs is not perfect, but it does a reasonable job of explaining the patterns used and how to use them. Personally, I would disagree that the lack of an event for dealing with asynchronous logic indicates that the model "is not very comprehensive". I don't think it's reasonable to expect every asynchronous API to support every possible implementation, or even all of the common patterns in .NET. The IAsyncResult design provides quite a lot of flexibility and frankly I think it's a better fit for this particular situation, because it is well-defined how the Begin and End methods should work given the existing synchronous method they correspond to. Pete
Show quote
"Peter Duniho" <NpOeStPe***@NnOwSlPiAnMk.com> schrieb In order to avoid a lengthier discussion, I only say that I have to accept > Armin Zingler wrote: > > [...] > > PRB: > > If I call Stop, the callback procedure is called even though no > > connection has been made. This leads to an ObjectDisposedException > > when calling EndAcceptTcpClient. > > > > Questions: > > - Why is the callback called at all? There is no incoming > > connection. > > The callback simply notifies you that the operation has completed. It's > not restricted to successful completions. it like it is. Though, an event driven model (ConnectionRequest Event) would be easier to use, IMO. Thanks. Armin "Armin Zingler" <az.nospam@freenet.de> wrote in message I've played with a number of models for doing this, and the Event Stuff news:O$yGKiQEIHA.1316@TK2MSFTNGP02.phx.gbl... > "Peter Duniho" <NpOeStPe***@NnOwSlPiAnMk.com> schrieb >> >> The callback simply notifies you that the operation has completed. It's >> not restricted to successful completions. > > In order to avoid a lengthier discussion, I only say that I have to accept > it like it is. Though, an event driven model (ConnectionRequest Event) > would be easier to use, IMO. always starts out easier, but ends up as problem later down the line. I quite like the Async stuff as it sits in the .Net framework... -- Chris Mullins
Show quote
"Chris Mullins [MVP - C#]" <cmull***@yahoo.com> schrieb Ok, thanks. Do you happen to have a link to a good tutorial about using the> "Armin Zingler" <az.nospam@freenet.de> wrote in message > news:O$yGKiQEIHA.1316@TK2MSFTNGP02.phx.gbl... > > "Peter Duniho" <NpOeStPe***@NnOwSlPiAnMk.com> schrieb > > > > > > The callback simply notifies you that the operation has > > > completed. It's not restricted to successful completions. > > > > In order to avoid a lengthier discussion, I only say that I have > > to accept it like it is. Though, an event driven model > > (ConnectionRequest Event) would be easier to use, IMO. > > I've played with a number of models for doing this, and the Event > Stuff always starts out easier, but ends up as problem later down > the line. > > I quite like the Async stuff as it sits in the .Net framework... TcpClient class (apart from MSDN lib)? (for example, samples that also include none-standard situations). Armin Armin Zingler wrote:
> Ok, thanks. Do you happen to have a link to a good tutorial about using the What sort of "non-standard situations"?> TcpClient class (apart from MSDN lib)? (for example, samples that also > include none-standard situations). I think the MSDN docs are pretty good, except that if you are using TcpClient and intend to use it with asynchronous API, you're going to find yourself in the samples for async i/o using the NetworkStream class, and if I recall correctly those samples aren't actually very good (I think the NetworkStream.EndRead sample doesn't even work). A better bet would be to look at the samples for the async methods on the Socket class. I think those samples are pretty good. You may find that you'll prefer to use the Socket class directly anyway (there's no reason not to use TcpClient, except that a Socket turns out to be very similar to a Stream anyway when dealing with TCP, and so there's not really any practical difference between using Socket directly and using the NetworkStream you get from a TcpClient). I don't think the MSDN samples will cover "non-standard situations", but that's what the newsgroups are for :). As long as you stay away from the samples that come with NetworkStream, I think MSDN should give you a good start though. Pete "Peter Duniho" <NpOeStPe***@NnOwSlPiAnMk.com> schrieb My current issue is how to asynchronously cancel sending without throwing> Armin Zingler wrote: > > Ok, thanks. Do you happen to have a link to a good tutorial about > > using the TcpClient class (apart from MSDN lib)? (for example, > > samples that also include none-standard situations). > > What sort of "non-standard situations"? an exception and how to find out how many bytes have already been sent. You don't have to make any efforts to elaborate on this (partially it's clear meanwhile). Just wanted to know whether anybody has a link where I can read it up on my own. I don't have more specific questions currently but I think that more will come. :-) > [...] Thank youArmin Armin Zingler wrote:
>> What sort of "non-standard situations"? Well, I will anyway, since the answer may not be what you expect. :)> > My current issue is how to asynchronously cancel sending without throwing > an exception and how to find out how many bytes have already been sent. > > You don't have to make any efforts to elaborate on this The only way to cancel data you've already sent is to close the connection. This can be done at any time, including while you have an outstanding asynchronous i/o request. The only way to find out how many bytes have already been sent after you close the connection is to ask the recipient. There is no reliable way using TCP/IP, regardless of what API you use, to provide that information. I don't think you're likely to find sample code that addresses these specific scenarios. The first issue is trivial to deal with (close the socket), and the latter is too closely dependent on the exact application protocol. Pete Peter Duniho wrote:
> The only way to cancel data you've already sent is to close the Sorry, I think I wasn't very clear here (though from the second part of > connection. This can be done at any time, including while you have an > outstanding asynchronous i/o request. [...] my message, maybe you've inferred the correct meaning). You can't really cancel the data with certainty. You can close the connection, and that will possibly abort a transmission that's taking place. But you have no way to _guarantee_ that data you've already tried to send won't be sent. It might be or it might not be, and even if you don't receive notification of completion of the send, it's still possible that the data will have been sent successfully. My statement is correct, but re-reading it, it seems to imply that closing the connection _will_ for sure cancel the data. That's not actually the case. It _might_ cancel data you've already sent, and that's the only way to accomplish that, but there's no guarantee that it will actually work. Sorry for any confusion. Pete Armin Zingler wrote:
> In order to avoid a lengthier discussion, I only say that I have to It would be trivial for you to wrap the existing IAsyncResult pattern in > accept it like it is. Though, an event driven model (ConnectionRequest > Event) would be easier to use, IMO. an event-based pattern, if you feel that strongly about it. Pete |
|||||||||||||||||||||||