класс HttpWebRequest.BeginGetResponse

Мне нужно сделать асинхронный запрос к веб-ресурсу и использовать пример с этой страницы (ссылка на полный пример):

HttpWebRequest myHttpWebRequest= (HttpWebRequest)WebRequest.Create("http://www.contoso.com");
RequestState myRequestState = new RequestState();  
myRequestState.request = myHttpWebRequest;
// Start the asynchronous request.
IAsyncResult result=
        (IAsyncResult) myHttpWebRequest.BeginGetResponse(new AsyncCallback(RespCallback),myRequestState);

но когда я тестирую приложение, выполнение замораживается (на 2-3 сек) в последней строке этого кода (я могу посмотреть его с помощью отладчика).

почему? Это моя ошибка или это стандартное поведение функции?

4 ответов


вы можете попробовать, я уверен, что это лучше

private void StartWebRequest(string url)
{
   HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
   request.BeginGetResponse(new AsyncCallback(FinishWebRequest), request);
}

private void FinishWebRequest(IAsyncResult result)
{
   HttpWebResponse response = (result.AsyncState as HttpWebRequest).EndGetResponse(result) as HttpWebResponse;
}

из-за перекрестного потока textbox'value, но это приложение wpf, которое я переставлю, кстати, вы можете использовать webclient как

 private void tbWord_TextChanged(object sender, TextChangedEventArgs e)
    {
        WebClient wc = new WebClient();
        wc.DownloadStringCompleted += HttpsCompleted;
        wc.DownloadStringAsync(new Uri("http://en.wikipedia.org/w/api.php?action=opensearch&search=" + tbWord.Text)); 
    }
    private void HttpsCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error == null)
        {

             //do what ever 
             //with using e.Result
        }
    } 

реакция происходит в отдельном потоке. Winforms не являются многопоточными, поэтому вам придется отправить вызов в том же потоке, что и форма.

вы можете сделать это, используя внутренний цикл обработки сообщений окна. К счастью, .NET предоставляет способ сделать это. Для этого можно использовать методы Invoke или BeginInvoke элемента управления. Первый блокирует текущий поток, пока поток пользовательского интерфейса не завершит вызываемый метод. Позже делает это асинхронно. Если нет очистки, вы можете использовать последний для того, чтобы "выстрелил и забыл"

чтобы это работало в любом случае, вам нужно создать метод, который вызывается BeginInvoke, и вам понадобится делегат, чтобы указать на этот метод.

См. Раздел Управление.Вызов и контроль.BeginInvoke в MSDN для получения более подробной информации.

есть образец по этой ссылке:https://msdn.microsoft.com/en-us/library/zyzhdc6b (v=против 110).aspx

Update: как я просматриваю мой профиль, потому что я забыл, что у меня есть учетная запись здесь-я заметил это, и я должен добавить: что-нибудь после 3.5 или когда они значительно изменили асинхронную модель резьбы здесь из моей рулевой рубки. Я выхожу профессионально, и хотя я все еще люблю ремесло, я не слежу за каждым продвижением. Вот что я могу вам сказать.--13-->должны работа во всех версиях .NET, но это не может быть абсолютной вершиной производительности 4.0 и выше или на Mono / Winforms-эмуляции, если это все еще вокруг. На светлая сторона, любой хит обычно не будет плохим вне серверных приложений, и даже внутри, если threadpool делает свою работу. Поэтому не фокусируйте усилия по оптимизации здесь в большинстве случаев, и, скорее всего, он будет работать на "урезанных" платформах, на которых вы видите такие вещи, как мобильные пакеты C#, хотя я должен был бы смотреть, чтобы быть уверенным, и большинство из них не запускают winforms, но некоторые циклы спиновых сообщений, и это тоже работает. В принципе, это не "лучший ответ" для новейших платформ в каждом последнем случае. Но в нужном случае он может быть более портативным. Если это помогает одному человеку избежать ошибки в дизайне, то стоило потратить время, чтобы написать это. =)


вы можете использовать BackgroundWorker add сделать все это в DoWork


Это стандартное поведение.

с документация по HttpWebRequest.Метод BeginGetResponse:

метод BeginGetResponse требует выполнения некоторых задач синхронной настройки (например, разрешение DNS, обнаружение прокси-сервера и подключение сокета TCP), прежде чем этот метод станет асинхронным. [...] для завершения начальной синхронной настройки может потребоваться значительное время (до нескольких минут в зависимости от настроек сети) задачи перед исключением для ошибки или метод успешно выполняется.

чтобы избежать ожидания установки, вы можете использовать HttpWebRequest.Способ BeginGetRequestStream но имейте в виду, что:

приложение не может смешивать синхронные и асинхронные методы для конкретного запроса. При вызове метода BeginGetRequestStream необходимо использовать метод BeginGetResponse для получения ответа.