I think this question is really about my understanding of Garbage collection and variable references. But I will go ahead and throw out some code for you to look at.
// Please note do not use this code for async sockets, just to highlight my question
// SocketTransport
// This is a simple wrapper class that is used as the 'state' object
// when performing Async Socket Reads/Writes
public class SocketTransport
{
public Socket Socket;
public byte[] Buffer;
public SocketTransport(Socket socket, byte[] buffer)
{
this.Socket = socket;
this.Buffer = buffer;
}
}
// Entry point - creates a SocketTransport, then passes it as the state
// object when Asyncly reading from the socket.
public void ReadOne(Socket socket)
{
SocketTransport socketTransport_One =
new SocketTransport(socket, new byte[10]);
socketTransport_One.Socket.BeginRecieve
(
socketTransport_One.Buffer, // Buffer to store data
0, // Buffer offset
10, // Read Length
SocketFlags.None // SocketFlags
new AsyncCallback(OnReadOne), // Callback when BeginRead completes
socketTransport_One // 'state' object to pass to Callback.
);
}
public void OnReadOne(IAsyncResult ar)
{
SocketTransport socketTransport_One = ar.asyncState as SocketTransport;
ProcessReadOneBuffer(socketTransport_One.Buffer); // Do processing
// New Read
// Create another! SocketTransport (what happens to first one?)
SocketTransport socketTransport_Two =
new SocketTransport(socket, new byte[10]);
socketTransport_Two.Socket.BeginRecieve
(
socketTransport_One.Buffer,
0,
10,
SocketFlags.None
new AsyncCallback(OnReadTwo),
socketTransport_Two
);
}
public void OnReadTwo(IAsyncResult ar)
{
SocketTransport socketTransport_Two = ar.asyncState as SocketTransport;
..............
So my question is:
-
The first SocketTransport to be created (socketTransport_One) has a strong reference to a Socket object (lets call is ~SocketA~).
-
Once the async read is completed, a new SocketTransport object is created (socketTransport_Two) also with a strong reference to ~SocketA~.
Q1. Will socketTransport_One be collected by the garbage collector when method OnReadOne exits? Even though it still contains a strong reference to ~SocketA~
Thanks all!
Adam is right,
socketTransport_Oneis eligible for garbage collection as soon asOnReadOne()exits. However, eligibility doesn’t mean that garbage collection will actually happen right then.Brian is right too, in that you should always call
EndReceive(theEndXpair to anyBeginXmethod in general). This is according to MSDN. However, in the current implementation, you won’t leak any resources even if you fail to callEndReceive. The AsyncState is released as soon as your callback finishes. But then again, you should not rely on this.@Brian: About a Socket left without references when it still has work to do: it too is going to be garbage collected. Its
Dispose()method could wait for pending operations to finish, but I think right now this feature is disabled. So you won’t leak anything here either.I’ve put together a little toy to play with, I hope it helps to clear things up even more: