Отмена вызова Socket.xxxxAsync

После вызова Socket.Shutdown, Socket.Close и Socket.Disconnect, похоже, что Socket.ReceiveAsync не прерывается. Попытки повторно использовать объект SocketAsycEventArgs, используемый в вызове ReceiveAsync (предлагаемый в документации в качестве лучшей практики), приводят к ошибке:

Операция асинхронного сокета уже выполняется с использованием этого экземпляра SocketAsyncEventArgs

Что мне нужно сделать, чтобы получить ReceiveAsync, чтобы освободить его захват в этом экземпляре SocketAsyncEventArgs?

Изменить: я работал над этим, помещая ожидающий прием и не выполняя очистку до тех пор, пока не придет прием (i.e Completed отправлен). Но это не слишком хорошо. Не может ли он быть прерван, как API WebRequest?

Ответ 1

Не существует способа прервать асинхронный прием.

Когда сокет закрыт, это заставляет прием завершить, а свойство SocketError параметра SocketAsyncEventArgs для вашего метода обратного вызова будет иметь значение SocketError.OperationAborted. Когда это условие встречается, вы можете вернуть объект SocketAsyncEventArgs в повторно используемый пул.

Это показано в приведенном ниже примере . В частности, посмотрите на метод ProcessReceive(), который вызывает метод CloseClientSocket(), когда e.BytesTransferred == 0 или e.SocketError != SocketError.Success. Метод CloseClientSocket() - это то, где объект SocketAsyncEventArgs возвращается в пул.

Ответ 2

Наиболее вероятной причиной является повторное использование SocketAsyncEventArgs, которое вы вызываете:

SAE.Completed + = новый EventHandler (SocketEventArg_Completed);

Это приведет к тому, что ваш callback будет вызван несколько раз!!!

Обязательно установите только обработчик Completed.