2014-12-02 1 views
1

Прежде всего, я использую расширение WithCancellation от Stephen Toub, чтобы позволить мне прервать метод ReadStringAsync. Внутри это использует TaskCompletionSource и Tasks.WhenAny. Подробности здесь; http://blogs.msdn.com/b/pfxteam/archive/2012/10/05/how-do-i-cancel-non-cancelable-async-operations.aspxInvalidOperationException при удалении объекта HttpContent во время чтения

Исключение составляет бросок из-за ключевого слова Using. Чтение все еще продолжается, когда удаляется End Using, который располагает внутренним потоком объекта Response.Content. Я понимаю, что чтение все еще работает в фоновом режиме, и я не возражаю, пока мой код может продолжаться, не зациклившись на длинном чтении.

Не уверен HttpClient свойства таймаута применяются при выполнении этого вида чтения (запрос выполнен с HttpCompletionOption.ResponseHeadersRead, поэтому у меня нет содержимого до того, как будет сделано чтение). Кроме того, у меня может возникнуть проблема, когда код зацикливается на чтении из-за плохого прокси-сервера, поэтому мне нужно отменить его.

Что я не понимаю;

  1. Почему исключение не попало в мои блоки try/catch?
  2. Как это исправить, чтобы я мог прервать чтение и игнорировать исключение?

Невозможно удалить Using блок, потому что все объекты HttpReponseMessage завернуты в Using, поэтому, когда HttpResponseMessage расположено у меня та же проблема.

Public Async Function GetResponseStringAsync(Response As HttpResponseMessage) As Tasks.Task(Of String) 

    Dim TimeoutToken As New CancellationTokenSource 
    TimeoutToken.CancelAfter(DefaultTimeout) 

    Try 

     Using Response.Content 
     Try 
      Return Await Response.Content.ReadAsStringAsync.WithCancellation(TimeoutToken.Token).ConfigureAwait(False) 
     Catch ex As Exception 
     End Try 
     End Using 
    Catch ex As Exception 

    End Try 

    Return Nothing 
    End Function 

Это выход InvalidOperationException, выбрасываемые.

System.InvalidOperationException: Can not access a closed Stream. 
    at System.Net.GZipWrapperStream.EndRead(IAsyncResult asyncResult) 
    at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.EndRead(IAsyncResult asyncResult) 
    at System.Net.Http.StreamToStreamCopy.BufferReadCallback(IAsyncResult ar) 

EDIT: после 72 часов комментариев, опросов или ответов. Что-то не так с вопросом?

ответ

1

Звонок на Response.Content.ReadAsStringAsync не блокируется. Он возвращается немедленно (в конце концов, это асинхронный), который запускает вызов Dispose в Контенте из предложения finally оператора using, который закрывает базовый поток и, таким образом, вызывает исключение.

Поток уже закрыт к моменту попытки чтения. Чтобы удалить содержимое после чтения, вы можете использовать следующее:

ContinueWith(t => { response.Content.Dispose(); return t.Result; }); 

Надеюсь, это поможет.

 Смежные вопросы

  • Нет связанных вопросов^_^