【发布时间】:2011-02-27 16:40:51
【问题描述】:
我在使用异步套接字调用实现连接超时时遇到问题。
我的想法是我在 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 线程还是不同的线程:
【问题讨论】: