繁体   English   中英

C#SocketAsyncEventArgs停止触发完成的事件

[英]C# SocketAsyncEventArgs stops firing completed event

我注意到一个问题,其中SocketAsyncEventArgs的.Completed事件似乎停止触发 相同的SAEA可以正确触发并在池中多次替换,但是最终所有实例都将停止触发,并且由于在池中替换它们的代码在事件处理程序中,因此池为空。

以下情况显然也是正确的:

1)似乎仅在服务器端套接字将数据发送到所连接的客户端之一时才会发生。 当同一类作为客户端连接时,它似乎没有故障。

2)它似乎在高负载下发生。 线程数似乎一直在增加,直到最终发生错误为止。

3)在类似压力下的测试设备似乎永远不会出现故障。 (每秒只有20条消息,并且测试装备已被证明可以达到20K)

我将无法粘贴相当复杂的代码,但这是我的代码说明

1)主要的灵感是这样的: http : //vadmyst.blogspot.ch/2008/05/sample-code-for-tcp-server-using.html 它显示了如何使用事件连接完成端口,如何通过TCP连接获取大小不同的消息,等等。

2)我有一个字节缓冲区,其中所有SAEA都有一个不重叠的部分。

3)我有一个基于阻塞集合的SAEA对象池。 如果池为空的时间太长,则会引发此错误。

4)作为服务器,我保留了从AcceptAsync函数返回的套接字的集合,该集合由客户端的端点索引。 单个进程可以将一个实例用作服务器,也可以将多个实例用作客户端(形成Web)。 它们共享SAEA的数据缓冲区和池。

我知道很难解释这一点。 我整天都在调试它。 只是希望有人听说过或有有用的问题或建议。

目前,我怀疑某种线程耗尽,导致SAEA无法调用完成。 或者,在传出缓冲区上出现某种缓冲区问题。

因此,调试的另一天,最后我得到了解释。

1)SAEA无法发送已完成的事件,因为它们无法发送更多消息。 Wireshark揭示这是由于TCP窗口为空。 (TCP ZeroWindow)

2)TCP窗口正在清空,因为网络层正在向上传递一个事件,该事件花费了太长时间才能完成,即网络层和UI之间没有生产者/消费者。 因此,网络op必须在发送ACK之前等待屏幕绘制。

3)花了太长时间的事件是GUI上事件处理程序中的屏幕绘制。 测试平台是一个控制台窗口(一个汇总传入消息的窗口),因此这就是为什么它在高得多的负载下不会引起问题的原因。 通常不要在每条消息上重画屏幕,但这是发生的,因为该项目尚未完成。 重提率将在以后确定。

4)短期解决方案只是确保没有GUI阻止演出。 一个更强大的解决方案可能是在网络层创建生产者/消费者。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM