Re: async sockets and threading

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Peter Duniho wrote:
On Tue, 21 Oct 2008 23:24:03 -0700, Alexander Gnauck
<gnauck@xxxxxxxxxxxxxx> wrote:

Peter Duniho wrote:
Please post a concise-but-complete code sample here.

ok, here is the example: [...]

Thanks for the example. With that in hand, it looks to me as though
the problem is related to garbage collection. In particular, it
appears that the JIT compiler figures out that you don't refer to the
_socket or _stream class members once the thread you started exits,
and it makes those members eligible for garbage collection. And of
course, when that happens (well, once the finalizer is run), the
connection winds up closed.
I added some synchronization to ensure that the Open() method doesn't
return until the EndSend() callback has been executed, and that
reliably makes the problem go away. That seems to confirm the GC as
the culprit.

What if you instead saved the IAsyncResult returned by BeginConnect into a
static variable? Perhaps that is what is being collected (though presumably
the same one gets passed to the completion routine)?


Now, whether that's _correct_ behavior, I'm not entirely sure. It
_seems_ like a .NET bug to me. In particular, those are static
members, and I would have thought all class static members would be
considered a root for the purpose of garbage collection. In fact,
one of the authoritative articles on .NET garbage collection seems to
say just that: " all the global and static object pointers in an
application are considered part of the application's roots" (from
http://msdn.microsoft.com/en-us/magazine/bb985010.aspx).

So, at the very least, for this code example, it seems to me that the
GC is prematurely collecting the objects. If your real-world
scenario also keeps the objects in static members, then the same bug
would be affecting you.

I think the BCL should be keeping these objects alive completely independent
of the user's references from static members. After all, the only living
reference could be in the State parameter to BeginConnect.


Of course, if in your real-world scenario, these objects wind up
referenced by instance members that are in a class instance that
itself becomes unreachable due to the use of the thread, then _that_
would be expected behavior. The fix there would be, of course, to
keep a reference to the instance storing the socket and stream
instances, so that they remain reachable and uncollected.

In that case, presumably the completion routine would be a instance method,
so the AsyncCallback delegate passed to BeginConnect would reference the
instance and (should) keep it alive.


In either case, I think that the static-based version of the behavior
is a bug, and it would be very helpful if you would post a bug report
to the http://connect.microsoft.com/ web site, for the .NET Framework.

Pete


.



Relevant Pages

  • Re: async sockets and threading
    ... In particular, it appears that the JIT compiler figures out that you don't refer to the _socket or _stream class members once the thread you started exits, and it makes those members eligible for garbage collection. ... In particular, those are static members, and I would have thought all class static members would be considered a root for the purpose of garbage collection. ... If your real-world scenario also keeps the objects in static members, then the same bug would be affecting you. ... The fix there would be, of course, to keep a reference to the instance storing the socket and stream instances, so that they remain reachable and uncollected. ...
    (microsoft.public.dotnet.languages.csharp)
  • Group objects
    ... through the common instance reference. ... If two or more members have duplicate methods either the first ... algorithms and horizontal inheritance. ... Being born as a part of the dynamic language study the group object ...
    (comp.lang.misc)
  • Re: A very good blog about the Delphi 2007 Help Issue
    ... To be also 'critical', I'll dare to mention some points in the _present_ help system, ie. the latest .CHM files: ... is better to present the members also in an 'inherited' way and/or put a symbol to mark that this member is inherited. ... The VCL help is titled 'RAD Studio VCL Win32 Reference M-Z' while it contains in fact the entire reference. ... The Delphi compiler does not provide RTTI by default. ...
    (borland.public.delphi.non-technical)
  • Re: [Beginner] question on Class Diagram
    ... Flight: holds flight information ... The relationship simply defines the overall structure of how individual members of each class set may be logically related. ... in UML relationships are subdivided for specialized purposes like generalization and composition. ... There are three ways to implement a relationship: invoking a FIND search on the class set; passing an object reference as a method argument; and embedding a reference to another object in an object. ...
    (comp.object)
  • Re: How to free memory in Javascript?
    ... The only memory allocated here is the space allocated for i. ... How do i get rid of the reference to button? ... Whilst in some sense reference counting is a garbage collection pattern ...
    (microsoft.public.scripting.jscript)