У нас есть приложение, которое делает вызовы на удаленный веб-адрес с использованием класса 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;
}
}
}
Вы нашли причину этой ошибки? – billy