2013-08-07 4 views
2

У нас есть приложение, которое делает вызовы на удаленный веб-адрес с использованием класса HttpWebRequest, который мы получаем через метод WebRequest.Create.HttpWebRequest unhandled "invalidcastexception" casting HttpWebResponse to System.Exception

Это наш реальный код:

var request = (HttpWebRequest)WebRequest.Create(uri); 
request.Method = "HEAD"; 
request.Timeout = this.connectionTimeout; 

if (this.usePipelinedConnection) 
{ 
    request.KeepAlive = true; 
    request.Pipelined = true; 
} 

request.BeginGetResponse(cb => logService.EndGetRequestStream(cb), null); 

В настоящее время в недетерминистическую способом (не может найти шаблон, чтобы воспроизвести его), мы получим следующее сообщение об ошибке:

System.InvalidCastException

Unable to cast object of type 'System.Net.HttpWebResponse' to type 'System.Exception'.

с этим трассировка стека:

at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context)

at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult)

at System.Net.LazyAsyncResult.Complete(IntPtr userToken)

at System.Net.ContextAwareResult.CaptureOrComplete(ExecutionContext& cachedContext, Boolean returnContext)

at System.Net.ContextAwareResult.FinishPostingAsyncOp()

at System.Net.HttpWebRequest.BeginGetResponse(AsyncCallback callback, Object state)

Документация об этом методе сообщает о нескольких исключениях, которые могут быть выброшены, но InvalidCastException не является одним из тех, что означает, что он не обрабатывается в методе microsoft. Я начал копаться в источниках .Net, и я думаю, что нашел виновника. В методе HttpWebResponse.EndGetResponseStream, есть эта линия:

throw (Exception) lazyAsyncResult.Result; 

Это единственный бросок к Exception, присутствующих в этом методе, так что должно быть. Теперь метод реализован таким образом, что он достигнет этой строки только в том случае, если connectionstream равен null, поэтому свойство lazyasyncresult.Result должно содержать исключение. В моем случае, однако, ветвь достигнута, но lazyasyncresult.Result содержит HttpWebResponse, поэтому бокс терпит неудачу, и я получаю эту ошибку. Теперь у меня есть два соображения:

  • Если содержание lazyasyncresult.Result были правильными, он привел бы в любом случае (так как линия начинается с броска), но это было бы смысл ошибки;
  • Относящиеся к предыдущей точке, я думаю, что если у меня есть HttpWebResponse код филиала, который проливает не должен быть достигнут в любом случае

Теперь мои вопросы является простой простой: как я этого не происходило? Я делаю что-то неправильно в своем коде или это простая ошибка в методе MS?

Здесь, для справки, источник MS метода. Я добавил несколько комментариев по инкриминированной строке.

Спасибо всем за ваше время.

public Stream EndGetRequestStream(IAsyncResult asyncResult, out TransportContext context) 
    { 
     if (Logging.On) 
     Logging.Enter(Logging.Web, (object) this, "EndGetRequestStream", ""); 
     context = (TransportContext) null; 
     if (asyncResult == null) 
     throw new ArgumentNullException("asyncResult"); 
     LazyAsyncResult lazyAsyncResult = asyncResult as LazyAsyncResult; 
     if (lazyAsyncResult == null || lazyAsyncResult.AsyncObject != this) 
     throw new ArgumentException(SR.GetString("net_io_invalidasyncresult"), "asyncResult"); 
     if (lazyAsyncResult.EndCalled) 
     { 
     throw new InvalidOperationException(SR.GetString("net_io_invalidendcall", new object[1] 
     { 
      (object) "EndGetRequestStream" 
     })); 
     } 
     else 
     { 
     ConnectStream connectStream = lazyAsyncResult.InternalWaitForCompletion() as ConnectStream; 
     lazyAsyncResult.EndCalled = true; 
     if (connectStream == null) 
     { 
      if (Logging.On) 
      Logging.Exception(Logging.Web, (object) this, "EndGetRequestStream", lazyAsyncResult.Result as Exception); 

// Here result contains HttpWebResponse so the cast to Exception fails. 
// It would throw anyway (since there' a throw) but I think, since result contains a response 
// that the code shouldn't be hitting this if branch. 
      throw (Exception) lazyAsyncResult.Result; 
     } 
     else 
     { 
      context = (TransportContext) new ConnectStreamContext(connectStream); 
      if (Logging.On) 
      Logging.Exit(Logging.Web, (object) this, "EndGetRequestStream", (object) connectStream); 
      return (Stream) connectStream; 
     } 
     } 
    } 
+0

Вы нашли причину этой ошибки? – billy

ответ

2

Я еще не использовал эту библиотеку задач асинхронной работы и прощал, если это наивный вопрос. Но .. arent вы вызываете неправильную функцию EndGetXXX?

request.BeginGetResponse(cb => logService.EndGetRequestStream(cb), null);

Я не знаю, что эта переменная logService есть, но оно не должно быть вызовом EndGetResponse() вместо этого?

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