ChatApp客户端断开处理致CPU占用达50%,求解决方法
修复ChatApp客户端断开处理的CPU占用过高问题
问题说明
开发的ChatApp客户端断开处理程序可正常移除ListView中的断开客户端,但客户端断开时CPU占用率突然升至50%,改用Thread实现后问题依旧,需要解决该性能问题。
原实现代码:
Task.Factory.StartNew(() => { while (true) { try { if (!client.Client.Connected) { session.Stop(); session.tcpclient = null; Clients.Remove(session); listView1.Invoke((MethodInvoker)(() => { ListViewItem data = new ListViewItem(session.listItems); listView1.Items.RemoveAt((session.index)); listView1.Refresh(); })); } Thread.Sleep(500); } catch (Exception) { } } });
修复方案
1. 终止无意义的无限循环
当前代码的核心问题是:客户端断开后,循环没有终止,仍在每500ms重复执行无效判断,空catch还会掩盖异常导致循环无法停止,持续消耗CPU资源。
修改时,在完成断开处理逻辑后直接退出循环:
Task.Factory.StartNew(() => { while (true) { try { if (!client.Client.Connected) { session.Stop(); session.tcpclient = null; // 加锁保证集合操作的线程安全 lock (Clients) { Clients.Remove(session); } listView1.Invoke((MethodInvoker)(() => { // 校验索引有效性,避免越界异常 if (session.index >= 0 && session.index < listView1.Items.Count) { listView1.Items.RemoveAt(session.index); listView1.Refresh(); } })); // 处理完成后退出循环,停止空轮询 break; } Thread.Sleep(500); } catch (Exception ex) { // 不要吞掉异常,记录日志方便排查问题 Console.WriteLine($"断开处理异常: {ex.Message}"); // 异常时也退出循环,防止死循环 break; } } });
2. 优化TCP连接检测逻辑
client.Client.Connected的检测并不准确,它仅反映最后一次IO操作的状态,无法主动感知连接的真实断开状态。更可靠的方式是:
- 给
TcpClient设置接收超时时间,当读取操作超时或抛出异常时,直接判定连接断开 - 定期发送心跳包,若对方未在指定时间内回应,则判定连接断开
3. 精简UI与集合操作
- 操作
Clients集合时加锁,避免多线程并发修改引发的异常 - UI操作中无需创建新的
ListViewItem,直接通过有效索引移除即可,减少不必要的对象创建
内容的提问来源于stack exchange,提问作者Hdhdhbdhd Xghdhdhdhd
相关产品推荐
相关产品推荐

