HttpWebRequest.BeginGetResponse - PullRequest
       7

HttpWebRequest.BeginGetResponse

6 голосов
/ 21 февраля 2012

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

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 ]

6 голосов
/ 21 февраля 2012

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

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-приложение, я буду пометить это, кстати, вы можете использовать веб-клиент как

 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
        }
    } 
2 голосов
/ 26 декабря 2015

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

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

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

См. Control.Invoke и Control.BeginInvoke в MSDN для получения дополнительной информации.

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

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

1 голос
/ 20 июля 2016

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

Из документации по методу HttpWebRequest.BeginGetResponse :

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

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

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

1 голос
/ 23 сентября 2014

Вы можете использовать BackgroundWorker для добавления всего этого в DoWork

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