使用 .NET 6.0。
我這樣呼叫 BeginAccept :
AsyncCallback callback = new AsyncCallback(AcceptCallback);
object? state = this.listenSocket;
_ = this.listenSocket.BeginAccept(callback, state);
我的AcceptCallback方法按預期被呼叫。然后我必須呼叫EndAccept以獲取接收套接字:
private static void AcceptCallback(IAsyncResult result)
{
Socket? listenSocket = result.AsyncState as Socket;
if (listenSocket == null)
{
// note: This is impossible but it helps getting the possible
// null reference warnings out of the way.
throw new ArgumentNullException(nameof(result.AsyncState), "The state object is null.");
}
Socket receiveSocket = listenSocket.EndAccept(
out byte[] buffer,
out int bytesRead,
result); // and here it blows up
最后一次呼叫給了我一個“System.ArgumentException:'值不在預期范圍內。(引數'asyncResult')'”。
顯然最后一個引數有問題。這不是我提供的東西,它是我通過系統傳遞的結果引數(根據除錯器),它是正確的 System.Threading.Tasks.TaskToApm.TaskAsyncResult。我只是按照我找到的示例進行操作。
我一開始沒有new AsyncCallback()在呼叫中進行包裝,BeginAccept因為我不明白它有什么好處(不過我想知道)。我最初也有非靜態方法。因為我遇到了這個問題,所以我將其更改為更像原始示例,但仍然存在相同的例外。
問題是什么,我能做些什么來克服它?
[編輯]
正如 Hans Passant 所指出的,結果引數不應該是 a System.Threading.Tasks.TaskToApm.TaskAsyncResult,這會導致錯誤。互聯網上幾乎沒有關于 TaskAsyncResult 的討論或檔案,這讓我很懷疑,認為這可能是新框架代碼中的錯誤。所以我用 .NET 5.0 重建,但結果是一樣的。
我只是使用 System.Net.Sockets.Socket 類,自定義庫或類似的東西沒有什么特別的。
uj5u.com熱心網友回復:
看起來這是第一位:
AsyncCallback callback = new AsyncCallback(AcceptCallback);
object? state = this.listenSocket;
_ = this.listenSocket.BeginAccept(callback, state);
使它失敗。如果我將其更改為:
int maxSize = 0x2000; // 8K
AsyncCallback callback = new AsyncCallback(AcceptCallback);
object? state = this.listenSocket;
_ = this.listenSocket.BeginAccept(maxSize, callback, state);
它成功了,在 EndAccept 上不再有例外,我在 ReceiveCallback 中獲得了預期的資料(異步流程的下一步)。
因為我是套接字編程的新手,所以我認為從簡單開始是明智的,所以我使用了 BeginAccept 多載和最少的引數。我認為它會使用默認的最大尺寸。好吧,不管那個“簡單”的多載做什么,它都不好。
所以System.Threading.Tasks.TaskToApm.TaskAsyncResult結果引數的AcceptCallback型別非常好,沒有問題(我檢查過,它仍然是一樣的)。
我現在可以繼續了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/405115.html
標籤:
