我应该总是调用TcpClient.EndConnect(即使连接失败了吗?)

时间:2010-01-04 09:27:32

标签: c# asynchronous webclient tcpclient

C#有几个有用的类用于网络任务,如TcpClient和WebClient。两者都有BeginX方法(分别为BeginConnect和BeginGetResponse),根据MSDN,应始终跟随EndX。两者都接受一个操作完成后调用的委托。

但是,假设我们无法建立连接,因此调用这些方法会引发异常。我是否仍然应该调用相应的EndX方法,还是应该首先检查连接是否已建立,然后再调用它们?

或者,在以下示例中,我应该使用OnSocketConnected1还是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();
}

由于

5 个答案:

答案 0 :(得分:3)

MSDN Quote, TcpClient.BeginConnect

  

异步BeginConnect   操作必须通过调用完成   EndConnect方法。通常,   方法由asyncCallback调用   委派。

我认为这条规则没有例外。你的字段无关紧要(阅读:版本1,无条件地立即调用EndConnect)。

答案 1 :(得分:0)

我的直觉会说是,因为它可能会允许框架垃圾收集IAsyncResult对象

答案 2 :(得分:0)

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

答案 3 :(得分:0)

我认为第二个版本没有你认为它做的。 Socket.Connect返回有关最新IO命令的信息。在EndConnect完成之前,您将无法建立连接。

答案 4 :(得分:0)

根据我自己的经验,看起来socket.EndConnect()socket.Close()无关紧要。如果您未能建立连接,socket.Dispose方法(在套接字被销毁时将被调用)似乎试图断开连接。当我调用Dispose()EndConnect()Close(),或者只是将套接字放入USING块时,我会得到相同的行为 - 缓慢断开而不是即时响应。事实上,即使我想要它,我还没有办法阻止这种情况发生。