I am trying to connect to my server with a TcpClient.BeginConnect / TcpClient.EndConnect
combo. However, some things don't work as they should.
The scenario is as follows:
TcpClient.BeginConnect
client.Close()
gets called in the process which closes the socket which in turn stops the async operation)TcpClient
connection callback method happens giving IAsyncResult
TcpClient.EndConnect
method with the given IAsyncResult
NullReferenceException
happens on EndConnect
(?)BeginConnect
operation completes (which is strange, as callback has already been called).What happens here is that a NullReferenceException
is caught. As you can see from the picture above, neither client
nor ar
are null
. The problem is that the MSDN documentation for the EndConnect does not mention the case in which this exception is thrown.
So basically, I have no idea what is going on. The problem is that I am forced to wait for the app to close (as if the connection operation still waits for a timeout). If a server is online, it connects and disconnects just fine.
What does NullReferenceException
in this context mean? How to avoid BeginConnect
operation to block the application closing in case the connection can't be established?
Additional notes (requested in comments):
Here is the code to create the client (client is a member variable:
public void Connect()
{
try
{
lock (connectionAccess)
{
if (State.IsConnectable())
{
// Create a client
client = new TcpClient();
client.LingerState = new LingerOption(false, 0);
client.NoDelay = true;
State = CommunicationState.Connecting;
client.BeginConnect(address, port, onTcpClientConnectionEstablished, null);
}
else
{
// Ignore connecting request if a connection is in a state that is not connectable
}
}
}
catch
{
Close(true);
}
}
Also the Close method:
public void Close(bool causedByError)
{
lock (connectionAccess)
{
// Close the stream
if (clientStream != null)
clientStream.Close();
// Close the gateway
if (client != null)
client.Close();
// Empty the mailboxes
incomingMailbox.Clear();
outgoingMailbox.Clear();
State = causedByError ? CommunicationState.CommunicationError : CommunicationState.Disconnected;
}
}
The NullReferenceException
is probably due to TcpClient.Client
being null.
If you were to follow the MSDN Example for TcpClient.BeginConnect
and pass theTcpClient
object as the state object:
private void onConnEst(IAsyncResult ar)
{
try
{
TcpClient client = (TcpClient)ar.AsyncState;
if(client!=null && client.Client!=null)
{
client.EndConnect(ar);
}
}
catch(Exception ex){...}
}
This should handle the case when Close()
is called before the Callback.
Going back to your problem - how long does it take for the application to eventually close?
This obviously a bug inside the TcpClient class. I have also faced it. TcpClient.Dispose may set Client field to null but EndConnect does not expect that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With