3

有什么方法可以获取 TcpClient 异步连接的状态?使用以下代码,如何使用 Connected 属性获取客户端的状态?我尝试异步建立远程连接,但同时不要等待超过 5 秒......

TcpClient client = new TcpClient();

Task tsk = Task.Factory.StartNew(() =>
{
   client.ConnectAsync(host, port);

   // client.Connect   (this is always false)
});

tsk.Wait(5000);

// client.Connect   (or if I use it here, this is always false)
4

2 回答 2

14

No, @Jon is wrong! The IsCompleted will just tell you if the task has been completed, it doesn't not indicate that the connection has been made. For example, if no server is open on the specific address/port, IsCompleted will return true anyway... You should check IsFaulted instead.

Here is code, that I have put together from pieces of the internet and I have actually tested:

string address = "127.0.0.1";
int port = 8888;
int connectTimeoutMilliseconds = 1000;

var tcpClient = new TcpClient();
var connectionTask = tcpClient
    .ConnectAsync(address, port).ContinueWith(task => {
        return task.IsFaulted ? null : tcpClient;
    }, TaskContinuationOptions.ExecuteSynchronously);
var timeoutTask = Task.Delay(connectTimeoutMilliseconds)
    .ContinueWith<TcpClient>(task => null, TaskContinuationOptions.ExecuteSynchronously);
var resultTask = Task.WhenAny(connectionTask, timeoutTask).Unwrap();

resultTask.Wait();
var resultTcpClient = resultTask.Result;
// Or shorter by using `await`:
// var resultTcpClient = await resultTask;

if (resultTcpClient != null)
{
    // Connected!
}
else
{
    // Not connected
}
于 2016-11-07T01:46:01.303 回答
10

首先,不要自己创造新Task的;这是一个错误。ConnectAsync已经返回Task表示连接尝试的 a:

var tsk = client.ConnectAsync(host, port);
tsk.Wait(5000);

等待返回后,检查IsCompleted任务的属性;true当且仅当建立连接时才会如此。

于 2013-08-28T12:11:34.550 回答