Эффективно ли я закрываю TCP-клиент? - PullRequest
0 голосов
/ 04 мая 2018
TcpClient tcp = new TcpClient();
bool failed = false;
IAsyncResult connection = tcp.BeginConnect(host, port, null, null);
if (!connection.AsyncWaitHandle.WaitOne(_connectTimeout)) 
{
    failed = true;
    if (tcp.Client.Connected) 
    {
        tcp.GetStream().Close();
        tcp.Close();
    }
} 
else 
{
    if (!tcp.Connected) 
    {
        failed = true;
        if (tcp.Client.Connected) 
        {
            tcp.GetStream().Close();
        }
        tcp.Close();
    }
}
return tcp;

Код выше - это то, что я называю для подключения к хосту, порту прокси. WaitOne по сути является тайм-аутом. Если он возвращает false, время истекло.

Мой вопрос здесь, правильно ли я звоню Close / Dispose / GetStream().Close и т. Д. При каждом условии? Из того, что я могу сказать, я должен использовать EndConnect здесь с переменной подключения, но где бы я ни пытался его разместить, он дает мне SocketException, говорящее, что целевой машине отказано в подключении, но она либо не подключена, либо она уже подключена .

1 Ответ

0 голосов
/ 04 мая 2018

Это решило мой вопрос (это редактирование мной другого решения, кредит ниже):

TcpClient tcp = new TcpClient();
#region Try connect
IAsyncResult ar = tcp.BeginConnect(host, port, (ari) => {
    TcpClient tcpi = (TcpClient)ari.AsyncState;
    try {
        tcpi.EndConnect(ari);
    } catch { }
    if (tcpi.Connected) {
        return; //return IAsyncResult and waitone will be true
    }
    //otherwise it will close the tcpi and never return, causing the timeout to kickin.
    tcpi.Close();
}, tcp);
#endregion
#region If timed out, or not connected return null
if (!ar.AsyncWaitHandle.WaitOne(_connectTimeout, false) || !tcp.Connected) {
    return null; //this is my use case, you might want to do something different
}
#endregion
return tcp;

Кредит за ссылку на другой похожий вопрос:
@ JeroenMostert

Кредит на оригинальное решение по аналогичному вопросу:
@ Adster

...