我在使用异步套接字调用实现连接超时时遇到问题。
我的想法是在Socket对象上调用BeginConnect,然后在超时时间结束后使用计时器在套接字上调用Close()。
只要在GUI线程上创建套接字,这就可以正常工作 - Close方法立即返回,并执行回调方法。但是,如果在任何其他线程上创建套接字,则Close方法将阻塞,直到发生默认IP超时。
重现的代码:
private Socket client;
private void button1_Click(object sender, EventArgs e) {
// Creating the socket on a threadpool thread causes Close to block.
ThreadPool.QueueUserWorkItem((object state) => {
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IAsyncResult result = client.BeginConnect(IPAddress.Parse("144.1.1.1"), 23, new AsyncCallback(CallbackMethod), client);
// Wait for 2 seconds before closing the socket.
if (result.AsyncWaitHandle.WaitOne(2000)) {
MessageBox.Show("Connected.");
} else {
MessageBox.Show("Timed out. Closing socket...");
client.Close();
MessageBox.Show("Socket closed.");
}
});
}
private void CallbackMethod(IAsyncResult result) {
MessageBox.Show("Callback started.");
Socket client = result.AsyncState as Socket;
try {
client.EndConnect(result);
} catch (ObjectDisposedException) {
}
MessageBox.Show("Callback finished.");
}
如果删除QueueUserWorkItem行,在GUI线程上创建套接字,则套接字会立即关闭而不会阻塞。
任何人都可以了解正在发生的事情吗? 感谢。
编辑 - System.Net跟踪输出似乎有所不同,具体取决于它是在GUI线程上连接还是在另一个线程上连接:
答案 0 :(得分:0)
您是否尝试删除围绕Socket.Close()调用的“MessageBox.Show”调用?
答案 1 :(得分:0)
我无法想象的是它在GUI线程上立即关闭的原因。我在调用client.Close()。
之前尝试调用client.Shutdown()我还尝试在常规线程(Thread.Start())中运行套接字对象,而不是使用ThreadPool。这样你就可以保持对线程的引用并自己调用Thread.Interrupt()和/或Thread.Abort()。