簡體   English   中英

僅在 Windows XP 上異步接收的 UdpClient 異常

[英]UdpClient Exception on async reception only on Windows XP

我有 ac# 代碼,它在 Windows vista/seven 中運行良好,但在 Windows XP 上運行不正常。

有問題的部分是“多播”節點,它基本上通過多播地址+端口讀取和發送數據。

讀取/寫入網絡的部分是單例。

每個訪問此單例的線程都必須指示它們何時需要開始偵聽以及何時停止。

當至少一個線程需要“啟動”時監聽套接字,當所有線程“停止”時我們停止(它們必須給出一個 Guid 標記,即 Start 方法返回)。

這種啟動/停止機制是為了確保如果沒有線程需要查看網絡上發生的事情,我們就不會為此消耗內存。

我遇到的問題是,在 Windows XP 上,出現了以下異常:

System.Net.Sockets.SocketException (0x80004005): The I/O operation has been aborted because of either a thread exit or an application request
   at System.Net.Sockets.Socket.EndReceiveFrom(IAsyncResult asyncResult, EndPoint& endPoint)
   at System.Net.Sockets.UdpClient.EndReceive(IAsyncResult asyncResult, IPEndPoint& remoteEP)

經過一番搜索,發現在 Windows XP 及以下版本中,當線程結束時,操作系統會釋放其所有 I/O 資源。 VB.NET 3.5 SocketException 在部署上但不在開發機器上)。

有沒有辦法避免這種行為? 因為在我的情況下,我創建一個將在執行結束之前結束的線程是正常的,而且我不想釋放它的套接字?

如果不可能,你將如何處理?

異步操作的調用線程在操作完成之前終止。

異步 I/O 操作使用稱為 IOCP(I/O Completion Port)的機制在 I/O 操作結束時通知正在執行的線程。

在幕后,整個事情基於稱為重疊 I/O 的東西。 在 Windows Vista 中,重疊 I/O 的行為已更改,因此當調用線程中止時,I/O 操作不再被取消。

在 Windows Vista 之前(例如 XP),每當調用線程中止時,該線程啟動的任何重疊 I/O 都會被取消,這可能就是此異常的原因。

您可以在此處閱讀更多相關信息: http : //www.lenholgate.com/blog/2008/02/major-vista-overlapped-io-change.html

您無法覆蓋此行為,但您可以確保(例如,使用事件)不會嘗試使用創建線程不再處於活動狀態的任何 I/O 資源。

因此,這似乎是由於 Windows XP 會在線程結束時自動釋放線程創建的資源( 部署時出現VB.NET 3.5 SocketException,但在開發機器上則不然)。

因此,我的解決方法是讓一個線程將IsBackground屬性設置為 true,即在 BlockingCollection 上進行迭代。 當我需要再偵聽一個 IP 時,我將這個 IP 添加到阻塞集合中,然后該線程創建它。

由於此線程在整個應用程序生命周期中永遠不會結束,因此不會釋放資源。 我做了這個行為檢查Environment.OSVersion.Version.Major是否大於或等於 6,這是 Vista 版本號。

現在它就像所有版本的魅力一樣

在較新的 .NET FrameWork 版本上,這可以解決問題。

TaskEx.Run(() => _udp.BeginReceive(AsyncCallback, state)).ConfigureAwait(false);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM