【发布时间】:2011-08-01 11:02:32
【问题描述】:
我正在练习使用异步 CTP 框架,作为练习,我将创建一个能够查询服务器(使用任意协议)的 TCP 客户端。无论如何,由于连接问题,我被困在了很早的阶段。要么我还没有理解一些基本点,要么有什么奇怪的地方。
所以,这里是异步连接器:
public class TaskClient
{
public static Task<TcpClient> Connect(IPEndPoint endPoint)
{
//create a tcp client
var client = new TcpClient(AddressFamily.InterNetwork);
//define a function to return the client
Func<IAsyncResult, TcpClient> em = iar =>
{
var c = (TcpClient)iar.AsyncState;
c.EndConnect(iar);
return c;
};
//create a task to connect the end-point async
var t = Task<TcpClient>.Factory.FromAsync(
client.BeginConnect,
em,
endPoint.Address.ToString(),
endPoint.Port,
client);
return t;
}
}
我的意思是只调用这个函数一次,然后返回一个 TcpClient 实例以用于任何后续查询(此处未显示代码)。
在我的表单中,我将上面的函数调用如下:
//this method runs on the UI thread, so can't block
private void TryConnect()
{
//create the end-point
var ep = new IPEndPoint(
IPAddress.Parse("192.168.14.112"), //this is not reachable: correct!
1601);
var t = TaskClient
.Connect(ep)
.ContinueWith<TcpClient>(_ =>
{
//tell me what's up
if (_.IsFaulted)
Console.WriteLine(_.Exception);
else
Console.WriteLine(_.Result.Connected);
return _.Result;
})
.ContinueWith(_ => _.Result.Close());
Console.WriteLine("connection in progress...");
//wait for 2" then abort the connection
//Thread.Sleep(2000);
//t.Result.Client.Close();
}
测试是尝试连接远程服务器,但它必须不可访问(PC 开启,但服务已停止)。
当我运行 TryConnect 函数时,它会立即正确返回“正在连接...”,然后显示异常,因为远程端点已关闭。太棒了!
问题是返回异常需要几秒钟,我想给用户机会取消正在进行的操作。根据 MSDN 关于 BeginConnect 方法的规范,如果您希望中止异步操作,只需在工作套接字上调用 Close。
所以,我尝试在末尾添加几行(如上所述注释掉),以便模拟用户在 2 秒后取消。结果看起来像是应用程序的挂起(沙漏)。通过暂停 IDE,它会在最后一行 t.Result.Client.Close() 处停止。但是,通过停止 IDE,一切都会正常关闭,无一例外。
我也试过直接关闭客户端为t.Result.Close(),但是完全一样。
是我,还是连接过程有什么问题?
非常感谢。
【问题讨论】:
标签: c# sockets asynchronous connection task