Question

C# has several useful classes for networking tasks such as TcpClient and WebClient. Both have BeginX methods (BeginConnect and BeginGetResponse respectively) that according to MSDN should always be followed by EndX. Both accepts a delegate that is called once the operation is complete.

However, say we fail to establish a connection, and thus calling those methods would throw an exception. Should I still call the respective EndX methods, or should I first check whether the connection was established, and only then call them?

Alternatively, in the following example, should I use OnSocketConnected1 or OnSocketConnected2?

static TcpClient m_client;

private static void OnSocketConnected1 (IAsyncResult asynchronousResult)
{
  try
  {
    m_client.EndConnect(asynchronousResult);
  }
  catch { }
}

private static void OnSocketConnected2(IAsyncResult asynchronousResult)
{
  if (m_client.Connected)
  {
    try
    {
      m_client.EndConnect(asynchronousResult);
    }
    catch { }
  }
}

static void Main(string[] args)
{
  m_client = new TcpClient();
  m_client.BeginConnect("http://www.example.com", 555, OnSocketConnected, null);
  Console.ReadLine();
}

Thanks

Was it helpful?

Solution

MSDN Quote, TcpClient.BeginConnect

The asynchronous BeginConnect operation must be completed by calling the EndConnect method. Typically, the method is invoked by the asyncCallback delegate.

I see no exception to that rule here. And your fields shouldn't matter (read: Version 1, call EndConnect unconditionally, right away).

OTHER TIPS

My instinct would say yes, as it would probably allow the framework to garbage-collect the IAsyncResult object.

private static void OnSocketConnected1 (IAsyncResult asynchronousResult)
{
  try
  {
    m_client.EndConnect(asynchronousResult);
  }
  catch { }
}

I don't think the second version does what you think it does. Socket.Connect returns information about the most recent IO command. You won't have a connection until EndConnect completes.

From my own experience, it looks like socket.EndConnect() or socket.Close() are irrelevant. If you failed to make a connection, the socket.Dispose method (which will get called when the socket is destroyed) appears to be trying to disconnect anyway. When I call Dispose(), EndConnect() or Close(), or simply put the socket into a USING block, I get the same behaviour - a slow disconnection rather than an instant response. In fact, I haven't found a way to stop this happening even if I wanted it to.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top