Re: Thread safety of asynchronous sockets, also - documentation vs reality
From: Sean Hederman (usemy_at_blogentry.com)
Date: 03/16/05
- Next message: Sean Hederman: "Re: Thread safety of asynchronous sockets, also - documentation vs reality"
- Previous message: Quimbly: ".NET Framework v2.0.41115"
- In reply to: cg: "Re: Thread safety of asynchronous sockets, also - documentation vs reality"
- Next in thread: Mochuelo: "Re: Thread safety of asynchronous sockets, also - documentation vs reality"
- Messages sorted by: [ date ] [ thread ]
Date: Wed, 16 Mar 2005 18:31:27 +0200
"cg" <nunya@damspam.com> wrote in message
news:Xns961BB5BC75B0kenwoodfanrrcom@24.93.44.119...
>I am the original poster, and thank you for your response! See my
> comments below.
>
> "Sean Hederman" <usemy@blogentry.com> wrote in
> news:d18e08$sjk$1@ctb-nnrp2.saix.net:
>
>>> "Before calling BeginReceive, you need to create a callback method
>>> that implements the AsyncCallback delegate. This callback method
>>> executes in a separate thread and is called by the system after
>>> BeginReceive returns. [.....] The EndReceive method will block
>>> until data is available."
>
>> But doesn't say how long after BeginReceive returns. I can see how it
>> would be confusing though.
>
> Well, why not just say it will be called by the system when data has been
> read and is available? It's more than confusing, it's downright
> misleading, especially when you toss in the statement about how
> EndReceive blocks until data is available. If you only call EndReceive in
> your receive callback, EndReceive NEVER blocks, because data is always
> available at that point, correct? Am I right in guessing that you can
> pass null for your callback, and call EndReceive directly after calling
> BeginReceive, thereby causing a synchronous read? If that is the case,
> the docs make more sense (although they are still a bit misleading), but
> why wouldn't you just use a synchronous Socket instead?
You are right here. Passing a null in for a callback does mean that you
would have to call EndReceive in your main thread. The advantage here is
that any ref, out and returns from EndReceive will be in the caller's thread
context, and thus will not need any synchronization.
Think about a scenario such as a server listener. It may want to start the
receive, and also do some preparation work for when the data comes in. Thus,
it uses the synchronous EndReceive, since it doesn't mind blocking once it's
finished it's prep work. Another situation could be where the main thread
occasionally polls the delegate to see if it has completed, and if it hasn't
does something else. Never really saw much point in that myself (except for
keeping your thread count down). Finally, you have the "true" asynchronous
situation where there is no blocking on the socket at all, but you may get
synchronisation issues when transferring the received information back to
the calling thread.
>> Not entirely correct. All it means is that responsibility for thread
>> safety is your problem. You don't have to lock everything, but you
>> must consider each variable and whether it is likely to be accessed by
>> another thread while a thread is using it; e.g. is it likely that your
>> Socket class will be getting called by the UI thread at the same time
>> as the callback is being executed?
>
> Sure, I understand what thread safety means, I guess I didn't make it
> clear that concurrency is indeed an issue in my project. However, it
> might be useful to have a bit more information than just that the class
> is not thread safe. It seems weird to me that calling BeginSend during a
> Receive callback could cause a problem, for instance, unless the
> underlying object has some sort of cross-dependency on the sending and
> receiving sides. The very idea that I have to synchronize access to an
> object which exposes an asynchronous API.... well just say that out loud
> and see if you don't laugh. :) Before you reply, let me say that I do
> realize that Socket also exposes a synchronous API. Perhaps that is the
> problem. We might do better if we had a Socket class and an AsyncSocket
> class.
All non-thread safe objects are thread safe if called from one thread ;D I
know I'm stating the obvious, but all you need to do is ensure that only one
thread "owns" a Socket. It may be asked to do things to the Socket, but it
should never allow other threads to access the Socket directly. The only
exception would be the completion threads which are allowed to call
EndReceive and that's it. If you can do that, then the Socket will be safe
as houses, and won't require any synchronisation code at all. As for an
AsyncSocket class, it isn't really needed since Begin/EndReceive allow the
non-thread safe socket to operate asynchronously, which is enough for most
purposes.
> It sure would be nice if somebody with knowledge of the internals could
> clear this up!
>
>> When MS say that a class is not thread safe they simply mean that they
>> have put no locking and synchronisation code in at all, and that such
>> actions are completely up to you. A rule of thumb is that static
>> members should be thread-safe whilst instance members are not.
>>
>> So, to summarize; your interpretation of the Socket class is the
>> correct one, the docs are a bit ambiguous. MS will *not* change Socket
>> to "conform" to the docs since that is not the required behaviour.
>
> I want to quibble that it is the *documented* behavior, but instead I
> will say thanks very much for your post! :)
:-)
My pleasure
> Take care,
>
> Christopher
- Next message: Sean Hederman: "Re: Thread safety of asynchronous sockets, also - documentation vs reality"
- Previous message: Quimbly: ".NET Framework v2.0.41115"
- In reply to: cg: "Re: Thread safety of asynchronous sockets, also - documentation vs reality"
- Next in thread: Mochuelo: "Re: Thread safety of asynchronous sockets, also - documentation vs reality"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|