Отмена вызова 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.