【发布时间】:2012-04-12 20:06:37
【问题描述】:
我用 C# 编写了一个 TCP 服务器应用程序。应用程序监听入站连接
在主监听线程中使用 TcpListener.AcceptTcpClient() 方法。
当接收到连接时,TcpListener.AcceptTcpClient() 解除阻塞并返回 TCPClient 对象。
收到连接后,会创建一个新线程并开始将数据读写到新连接。
新线程由以下代码启动。
while(true)
{
TcpClient client = serverListener.AcceptTcpClient();
if (client.Connected)
{
Thread t = new Thread(delegate() { readWriteData(client); });
t.IsBackground = true;
t.Start(); /// Problem happens here. The thread gets stuck here and doesn't move further
}
}
应用程序运行良好,但有时在 Windows 7 机器上,应用程序突然停止侦听 tcp 连接。
分析此状态下应用程序的线程堆栈,(使用Microsoft stack explorer查看应用程序所有线程的堆栈)发现主监听线程卡在上面代码部分的以下行
t.Start(); /// Problem happens here. The thread gets stuck here and doesn't move further
我进行了大量研究,但找不到发生这种情况的原因。此行为仅在 Windows 7 系统中观察到。
谁能帮我解决这个问题。
按照 Rob 的建议,
我在这里发布由 windbg (sos) 显示的堆栈跟踪
0547eae0 7282e006 mscorwks!Thread::StartThread+0xc3, calling mscorwks!_EH_epilog3
0547eb00 727ac825 mscorwks!__SwitchToThread+0xd, calling mscorwks!__DangerousSwitchToThread
0547eb10 728b9c6f mscorwks!ThreadNative::StartInner+0x1ba, calling mscorwks!__SwitchToThread
0547eb58 727e4b04 mscorwks!SafeHandle::DisposeNative+0x3a, calling mscorwks!LazyMachStateCaptureState
0547ebc8 728b9d80 mscorwks!ThreadNative::Start+0xa6, calling mscorwks!ThreadNative::StartInner
0547ec18 728b9d01 mscorwks!ThreadNative::Start+0x1f, calling mscorwks!LazyMachStateCaptureState
0547ec74 71de6afc (MethodDesc 0x71c13048 +0x8c System.Threading.Thread.Start()), calling mscorwks!ThreadNative::Start
0547ec8c 030e2a46 (MethodDesc 0x30da408 +0x25e WindowsService.Server.startListener()), calling (MethodDesc 0x71c13048 +0 System.Threading.Thread.Start())
【问题讨论】:
-
Thread.Start 不太可能没有返回。更有可能是您检查或确定错误的方法。是什么让您认为 Thread.Start 没有返回?
-
通常不建议每个连接都有一个线程;它不会缩放。您有多少传入连接?
-
挂起时您有多少活跃客户? - 每个客户端的线程并不总是很好地扩展。
-
你能直接确认这个行为吗(没有附加调试器,或者通过查看转储)?尝试在
t.Start()前后使用日志语句或Console.WriteLine,写出线程管理的ID 或类似的东西,然后确认您确实遇到了“之前”消息而没有相应的“之后”消息。 -
@KierenJohnstone 如帖子中所述,我使用 microsoft stack explorer 查看卡住线程的堆栈。每次出现这个问题,就说明主监听线程的状态是running,线程卡在Thread.start上
标签: c# multithreading windows-7 tcp