Socket接收数据入队后ConcurrentQueue.Count始终为0的问题排查
Socket通信Client类监听场景下ConcurrentQueue数据无法被ReadTimer处理的异常
一段已稳定运行多年的Socket通信Client类代码,仅在监听Socket端口并接受连接的场景下出现异常:EnqueueData方法已将数据成功入队(调试可见队列持续增长),但ReadTimer触发时ReadQueue.Count始终为0,无法处理队列中的数据;而主动连接Socket端口的场景下一切正常。
核心代码片段
Client类队列与定时器处理逻辑
protected ConcurrentQueue<byte[]> ReadQueue { get; } = new ConcurrentQueue<byte[]>(); private void ReadTimer_Tick(object sender, EventArgs e) { ReadTimer.Stop(); try { while (ReadQueue.Count > 0 && !IsDisposing) { try { if (this.ReadQueue.TryDequeue(out var data)) { [...] // 数据处理逻辑 } } catch (Exception ex) { [...] // 异常捕获逻辑 } } } catch (Exception) { [...] // 全局异常捕获逻辑 } finally { if (IsConnected && !IsDisposing) ReadTimer.Start(); } } protected void EnqueueData(IEnumerable<byte> data) { ReadQueue.Enqueue(data.ToArray()); }
ReadTimer每隔1毫秒触发,用于从ConcurrentQueue中取出数据并处理。
两种使用场景
场景1:主动连接(正常工作)
主动连接目标Socket端口,建立连接后调用Socket.BeginReceive方法。此场景下ReadTimer触发时ReadQueue.Count大于0,数据能被正常处理。
场景2:监听并接受连接(异常场景)
监听本地Socket端口并调用Socket.BeginAccept方法,在BeginAccept的回调方法中调用Socket.BeginReceive。
共用的接收启动方法
private void StartReceiving(SocketAnswerBuffer state) { try { Status = ClientStatus.Receiving; _ = state.Socket.BeginReceive( state.Buffer, 0, state.Buffer.Length, SocketFlags.None, ReceiveCallback, state ); } catch (Exception ex) { [...] // 异常捕获逻辑 } }
共用的接收回调处理
private void OnReceive(IAsyncResult result) { if (result.AsyncState is SocketAnswerBuffer state) { try { var size = state.Socket.EndReceive(result); if (size > 0) { var data = state.Buffer.Take(size).ToArray(); EnqueueData(data); } } catch (Exception ex) { [...] // 异常捕获逻辑 } finally { Status = ClientStatus.Connected; if (state != null && state.Socket.Connected) StartReceiving(state); } } }
异常现象说明
两种场景都会调用EnqueueData方法,但场景2中:
- 调试可见
EnqueueData执行后ReadQueue.Count大于0且队列持续增长 ReadTimer_Tick方法中ReadQueue.Count始终为0,无法处理数据- 代码中无清空或重新声明
ReadQueue的逻辑,仅ReadTimer_Tick会执行出队操作
内容的提问来源于stack exchange,提问作者Oliver
相关产品推荐
相关产品推荐

