簡體   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