2012-02-21 3 views
6

Мне нужно сделать запрос асинхронной к веб-ресурсу и использовать пример с этой страницы (link to full example):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 сек) на последняя строка этого кода (я могу посмотреть его с помощью отладчика).

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

ответ

6

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

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; 
} 

Из chross нити 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 
     } 
    } 
+0

Что такое параметр IAsyncResult во втором методе? Результат вызова request.BeginGetResponse()? – demas

+0

Как я вижу, это ничего не меняет. Вот полный код http://pastebin.com/trvq1qza. Окна графического интерфейса пользователя замораживаются в строке 18. – demas

+0

@demas i обновленный ответ. что работает на меня без замерзания –

1

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

2

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

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

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

Подробнее см. В разделе Control.Invoke и Control.BeginInvoke в MSDN.

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

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

1

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

Из documentation on HttpWebRequest.BeginGetResponse Method:

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

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

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

Смежные вопросы