Сбой HttpWebRequest после третьего вызова - PullRequest
0 голосов
/ 23 марта 2009

вот мой метод:

private static void UpdatePref(List<EmailPrefer> prefList)
{
    if(prefList.Count > 0)
    {
        foreach (EmailPref pref in prefList)
        {
            UpdateEmailRequest updateRequest = new UpdateEmailRequest(pref.ID.ToString(), pref.Email, pref.ListID.ToString());
            UpdateEmailResponse updateResponse =(UpdateEmailResponse) updateRequest.SendRequest();

            if (updateResponse.Success)
            {
                Console.WriteLine(String.Format("Update Succsesful.  ListID:{0}  Email:{2}  ID:{1}", pref.ListID, pref.Email, pref.ID));
                continue;
            }
            Console.WriteLine( String.Format("Update Unsuccessful.  ListID:{0}  Email:{2}  ID:{1}\n", pref.ListID, pref.Email, pref.ID));
            Console.WriteLine(String.Format("Error:{0}", updateResponse.ErrorMessage));
        }

        Console.WriteLine("Updates Complete.");
    }
    Console.WriteLine("Procses ended.  No records found to update");
}

список содержит около 84 допустимых записей, для которых он циклически обрабатывает и отправляет запрос API. Но он останавливается на 3-м вызове API и обрабатывает только 2 из 84 записей. Когда я отлаживаю, чтобы увидеть, что происходит, я вижу только то, что это останавливается здесь в моем методе SendRequest, не выпуская никакой ошибки. Он останавливается в GetRequestStream, и когда я перехожу к нему и пытаюсь продолжать, он просто останавливается, и мое приложение перестает работать без ошибок!

HttpWebRequest request = CreateWebRequest(requestURI, data.Length);
request.ContentLength = data.Length;
request.KeepAlive = false;
request.Timeout = 30000;

// Send the Request
requestStream = request.GetRequestStream();

WTF? В конце концов, если я продолжаю работать, я получаю сообщение об ошибке «Операция истекла». Но тогда почему первые 2 звонка прошли, а этот тайм-аут? Я не понимаю.

Кроме того, второй вопрос. Неэффективно ли создавать новый объект внутри моего foreach для отправки и получения? Но вот как я заглушил эти классы и потребовал, чтобы электронная почта, ListID и т. Д. Были требованием для отправки этого типа вызова API. Я просто не знал, нормально ли это или не эффективно создавать новый экземпляр через каждую итерацию в foreach. Может быть обычным делом, но мне это показалось странным и неэффективным.

Ответы [ 2 ]

1 голос
/ 23 марта 2009

РЕДАКТИРОВАТЬ: Кажется, вы ответили на свой вопрос уже в комментариях.

У меня нет личного опыта с этим, но, кажется, вам нужно позвонить близко по веб-запросу HTTP после получения ответа. Количество открытых соединений ограничено 2, и соединение не освобождается, пока вы не закроете (). См. http://blogs.msdn.com/feroze_daud/archive/2004/01/21/61400.aspx,, который дает следующий код для демонстрации симптомов, которые вы видите.

    for(int i=0; i < 3; i++) {
       HttpWebRequest r = WebRequest.Create(“http://www.microsoft.com“) as HttpWebRequest;
       HttpWebResponse w = r.GetResponse() as HttpWebResponse;
    }
0 голосов
/ 23 марта 2009

Одной из возможностей для этого тайм-аута является то, что сервер, с которым вы разговариваете, душит вас. Вы можете попытаться вставить задержку (возможно, секунду) после каждого обновления.

Если предположить, что UpdateEmailRequest и UpdateEmailResponse как-то получены из WebRequest и WebResponse соответственно, то создание запросов не так уж и неэффективно, как вы это делаете. Это довольно стандартно. Однако обратите внимание, что WebResponse - это IDisposable, что означает, что он, вероятно, выделяет неуправляемые ресурсы, и вы должны избавиться от них - либо вызвав метод Dispose. Примерно так:

UpdateEmailResponse updateResponse =(UpdateEmailResponse) updateRequest.SendRequest();
try
{
    if (updateResponse.Success)
    {
        Console.WriteLine(String.Format("Update Succsesful.  ListID:{0}  Email:{2}  ID:{1}", pref.ListID, pref.Email, pref.ID));
        continue;
    }
    Console.WriteLine( String.Format("Update Unsuccessful.  ListID:{0}  Email:{2}  ID:{1}\n", pref.ListID, pref.Email, pref.ID));
    Console.WriteLine(String.Format("Error:{0}", updateResponse.ErrorMessage));
}
finally
{
    updateResponse.Dispose();
}

Полагаю, вполне возможно, что отсутствие утилизации объектов ответа сохраняет открытое соединение с сервером, а время сервера истекает из-за слишком большого количества открытых соединений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...