Обслуживание HttpWebRequest и веб-ошибки http приводят к тому, что он возвращает «HRESULT E_FAIL» и «сервер не найден» - PullRequest
2 голосов
/ 15 ноября 2010

Я перебираю большой список объектов (1503) и вызываю метод сохранения в ServiceProxy, который я написал.Прокси-сервер службы использует новый сетевой стек в Silverlight 4 для вызова BeginGetRequestStream, чтобы запустить процесс асинхронной отправки моих объектов в службу Azure REST, которую я написал для сохранения объектов.Http метод, который я использую, это POST.Я знаю, что HttpWebClient достаточно умен, чтобы повторно использовать соединение Http, поэтому я не одновременно открываю 1503 соединения с сервером.Сохранение работает отлично, и все 1503 объекта сохраняются очень быстро.Однако, когда я снова пытаюсь сохранить те же объекты, я ожидаю получить код HttpStatus, запрещенный, потому что объекты уже существуют, и это код, который я настроил для возврата в свой веб-сервис Azure.На небольших группах объектов это работает как положено.Однако, когда я пытаюсь сохранить весь список из 1503 объектов, я получаю только 455 правильных ответов и 1048 ошибок, таких как «сервер не найден» и

System.Exception ---> System.Exception:Error HRESULT E_FAIL has been returned from a call to a COM component.
at
System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)...

. Интересно, существует ли какая-либо бухгалтерия илиобслуживание, которое я должен выполнять на моих экземплярах HttpWebClient, которыми я пренебрегаю, и именно это заставляет ошибки http генерировать исключения, но новые сохранения работают отлично.Вот мой код для обработки случаев ошибки:

private static void SendAncestorResponseCallback(IAsyncResult result)
    {
        var info = (SendAncestorInfo)result.AsyncState;

        try
        {
            var response = info.Request.EndGetResponse(result);
            info.Response = response;
        }
        catch ( Exception ex)
        {
            info.Error = ex;
        }

        info.MainThreadContext.Post(SendAncestorMainThreadCallback, info);
    }
    private static void SendAncestorMainThreadCallback(object state)
    {
        var info = (SendAncestorInfo)state;
        IAncestor origAncestor = info.Content;
        HttpWebResponse response = null;
        if (info.Error != null)
        {
            if ((info.Error as WebException) == null)
            {
                info.Callback(false, origAncestor, null, info.Error);
                return;
            }
            else //get response from WebException
            {
                response = (HttpWebResponse)(info.Error as WebException).Response;
            }
        }
        else  //get response from info.Response
        {
            response = info.Response as HttpWebResponse;
        } 
        if (response.StatusCode == HttpStatusCode.Created || response.StatusCode == HttpStatusCode.Forbidden)
        {
            var stream = response.GetResponseStream();
            using (var reader = new StreamReader(stream))
            {
                IAncestor retAncestor = XMLSerializerHelper.DeserializeObject<Ancestor>(reader.ReadToEnd());
                info.Callback(response.StatusCode == HttpStatusCode.Created, origAncestor, retAncestor, null);        
            }
        }
        else info.Callback(false, origAncestor, null, info.Error);
    }

с учетом того, как написан веб-сервис, я должен ожидать только http-коды статуса созданных или запрещенных, и, как я уже говорил с небольшими группами, это так.Тот факт, что я только начинаю получать ошибки, упомянутые ранее, заставляет меня чувствовать, что я делаю что-то не так с объектами HttpWebRequest и т. Д. Любая помощь будет принята с благодарностью.Спасибо.

- обновите здесь код, который генерирует запрос HttpWebRequest:

foreach (IAncestor ancestor in ancestors)
            {
                AncestorViewModel ancestorVM = new AncestorViewModel(ancestor);
                ancestorVM.Status = SaveStatus.Undefined;
                ParsedAncestors.Add(ancestorVM);
                _service.CreateAncestor(UserSrc, ancestor, (success, origAncestor, retAncestor, exception) =>
                    {
                        AncestorViewModel result = ParsedAncestors.First(a => a.Model.IdNo == origAncestor.IdNo);
                        if (exception == null)//web response was either Created or Forbidden
                        {
                            if (success)//Ancestor successfully created
                            {
                                savedAncestors++;
                                SuccessMessage = string.Format("{0} Saved\n", savedAncestors);
                                result.Status = SaveStatus.Saved;
                            }
                            else //Ancestor already existed
                            {
                                conflictAncestors.Add(origAncestor, retAncestor);
                                ConflictMessage = string.Format("{0} Conflicts\n", conflictAncestors.Count);
                                result.Status = SaveStatus.Conflicted;
                            } 
                        }
                        else //Show exception recieved from remote web service
                        {
                            //if (exception as WebException != null)
                            //{
                            //    //if exception is WebException get status code and description
                            //    HttpWebResponse rs = (HttpWebResponse)(exception as WebException).Response;
                            //    Message += string.Format("WebServer returned status code {0}: '{1}'\n", (int)rs.StatusCode, rs.StatusDescription);
                            //}
                            errors.Add(origAncestor, exception);
                            ErrorMessage = string.Format("{0} Errors\n", errors.Count);
                            result.Status = SaveStatus.Error;
                        }
                    });
            }

public void CreateAncestor(string userSrc, IAncestor ancestor, Action<bool, IAncestor, IAncestor, Exception> callback)
    {
        WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
        var request = (HttpWebRequest)WebRequest.Create(
            new Uri(string.Format("{0}/{1}/{2}", rootUri, AncestorsRestPoint, userSrc)));
        request.Method = "POST";
        request.ContentType = "application/xml";
        var info = new SendAncestorInfo
        {
            Request = request,
            Callback = callback,
            Content = ancestor,
            MainThreadContext = SynchronizationContext.Current
        };

        request.BeginGetRequestStream(SendAncestorRequestCallback, info);
    }
...