Нет, универсального способа отменить такую задачу не существует. Отмена зависит от API.
- Например, у
WebClient
есть метод Cancel
.
Socket
или FileStream
необходимо ввести Close
, чтобы отменить невыполненный вызов.
- У клиентов веб-сервисов есть даже разные способы прерывания вызовов.
- ...
Это связано с тем, что средство реализации операции ввода-вывода должно поддерживать отмену.
Может показаться заманчивым использовать NetworkStream.ReadAsync
и передать токен отмены, но это Stream.ReadAsync
. Последний просто выбрасывает токен. Принципиально не поддерживается.
Stream.ReadAsync
— это просто метод базового класса. Он ничего не делает сам по себе. Конкретные операции ввода-вывода выдаются только производными классами. Они должны изначально поддерживать отмену. Стрим ничего не может сделать, чтобы заставить их. Бывает, что NetworkStream
не поддерживает отмену.
Я понимаю, что вы хотите отменить операцию и оставить сокет открытым. Но это невозможно . (Субъективное примечание: это действительно печальное положение дел. Особенно если учесть, что Windows поддерживает отменяемый ввод-вывод на уровне Win32.)
Если вы по-прежнему хотите, чтобы ваше приложение быстро продолжило работу, несмотря на то, что операцию ввода-вывода нельзя отменить, просто игнорируйте результат этой задачи и продолжайте. Имейте в виду, что в конечном итоге ввод-вывод может завершиться и, например, слить данные из буферов сокетов или вызвать другие побочные эффекты.
"Отмена путем игнорирования" фактически делает позицию потока неопределенной. Поток становится непригодным для использования. На самом деле это не избавляет от необходимости открывать новый поток. Вам все равно придется избавиться от старого потока (в большинстве случаев) и открыть его заново. Кроме того, вы вводите параллелизм.
person
usr
schedule
27.07.2014
FromAsync
, которая принимает токен отмены. Одним из возможных решений было бы добавить еще один уровень — начать свое собственное действие сFromAsync
, а затем использовать другоеTask
, которое поддерживает отмену извне для чтения потока внутри пользовательского действия. - person keenthinker   schedule 27.07.2014NetworkStream.ReadAsync
, которые поддерживаютCancellationToken
? - person avo   schedule 27.07.2014CancellationToken.Register
и оттуда вызватьNetworkStream.Dispose
. Это должно отменить ожидающее чтение. - person avo   schedule 27.07.2014