我正在使用异步CTP框架进行实践,练习时我想创建一个TCP客户端,能够查询服务器(使用任意协议)。但是,我在连接的早期阶段遇到了问题。要么我还没有理解一些基本点,要么就有一些奇怪的问题。
因此,这是异步连接器:
我希望只调用一次此函数,接着返回一个TcpClient实例,以供后续查询使用(此处未显示代码)。
在我的表单中的某个位置,我按如下方式调用上述函数:
该测试旨在尝试连接远程服务器,但必须是不可访问的(计算机已开启,但服务已停止)。
当我运行TryConnect函数时,它会立即正确返回“连接正在进行中...”,然后显示一个异常,因为远程终点已关闭。太好了!
问题是需要几秒钟才能返回异常,我想让用户有机会取消正在进行的操作。根据MSDN关于BeginConnect方法的规范,如果您希望中止异步操作,请在工作套接字上调用Close。
所以,我尝试在最后添加了几行(如上所述被注释掉),模拟2秒后用户的取消操作。结果看起来像是应用程序挂起(沙漏)。通过暂停IDE,它停在最后一行t.Result.Client.Close()。但是,通过停止IDE,一切都正常关闭,没有任何异常。
我还尝试直接关闭客户端t.Result.Close(),但情况完全相同。
是我还是连接过程出了问题?
非常感谢。
因此,这是异步连接器:
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();
}
该测试旨在尝试连接远程服务器,但必须是不可访问的(计算机已开启,但服务已停止)。
当我运行TryConnect函数时,它会立即正确返回“连接正在进行中...”,然后显示一个异常,因为远程终点已关闭。太好了!
问题是需要几秒钟才能返回异常,我想让用户有机会取消正在进行的操作。根据MSDN关于BeginConnect方法的规范,如果您希望中止异步操作,请在工作套接字上调用Close。
所以,我尝试在最后添加了几行(如上所述被注释掉),模拟2秒后用户的取消操作。结果看起来像是应用程序挂起(沙漏)。通过暂停IDE,它停在最后一行t.Result.Client.Close()。但是,通过停止IDE,一切都正常关闭,没有任何异常。
我还尝试直接关闭客户端t.Result.Close(),但情况完全相同。
是我还是连接过程出了问题?
非常感谢。