2015-11-23 2 views
0

Вот что я сделал до сих пор:Silverlight - Подождите асинхронной задачи для завершения

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

Я создал свой URI

Uri address = new Uri("http://dev.virtualearth.net/REST/V1/Imagery/Metadata/OrdnanceSurvey/" + latitude + "," + longitude + "?+zl=" + zoomLevel + "&key="""); 

Я тогда сказал ему, где позвонить, когда операция имеет полный

WebClient webClient = new WebClient(); 
webClient.DownloadStringCompleted += WebClientDownloadString_Complete; 
webClient.DownloadStringAsync(address); 

Тогда я установить, что произойдет, когда завершена работа

private void WebClientDownloadString_Complete(object sender, DownloadStringCompletedEventArgs e) 
    { 
     if (e.Error == null) 
     { 

      string html = e.Result; 

      string[] parts = html.Split(','); 
      string[] URLs = parts[7].Split('"'); 
      URL = URLs[3].Replace("{subdomain}", "t0").Replace("{quadkey}", qk.Key).Replace(@"\", string.Empty); 


     } 
    } 

Есть ли способ, которым, когда веб-клиент вызывает URL-адрес, я жду, пока операция не завершится, и вызовет завершенный метод?

ответ

-1

Хотел сделать это сам некоторое время назад. Вот как я это сделал:

  // create a notifier which tells us when the download is finished 
      // in .net 4.5 DownloadFileTaskAsync can be used instead which simplyfies this task 
      AutoResetEvent notifier = new AutoResetEvent(false); 
      client.DownloadFileCompleted += (object sender, AsyncCompletedEventArgs e) => 
      { 
       notifier.Set(); 
      }; 

      try 
      { 

       client.DownloadFileAsync(downloadUrl, destination); 
       // wait for download to finish 
       notifier.WaitOne(); 
      ... 
+0

Хороший метод, но 'TaskCompletionSource' немного лучше (и не блокирует вызывающий поток) – BradleyDotNET

+0

я думаю, если он может использовать DownloadFileTaskAsync он мог бы сделать это еще лучше;) –

0

легко способ сделать это, чтобы просто использовать DownloadString вместо DownloadStringAsync. Вызов DownloadString будет блокирован (обязательно запустите его в фоновом потоке!), И вы можете выполнить цикл, как вы ожидаете.

Другой вариант - создать TaskCompletionSource и установить его в обработчике событий.

private TaskCompletionSource<bool> currentTask; 

private async Task GetURLs() 
{ 
    while (someCondition) 
    { 
     currentTask = new TaskCompletionSource<bool>(); 
     WebClient webClient = new WebClient(); 
     webClient.DownloadStringCompleted += WebClientDownloadString_Complete; 
     webClient.DownloadStringAsync(address); 

     await currentTask; 
    } 
} 

private void WebClientDownloadString_Complete(...) 
{ 
    //Process completion 

    //C# 6 null check 
    curentTask?.TrySetValue(true); 
} 

«GetURLS» будет блокировать асинхронно, пока значение задачи не установлен, а затем разрешить цикл, а для продолжения. Это имеет то преимущество, что не требуется явный фоновый поток.

+0

Я не возможно использовать ключевое слово async в VS2010. –

+0

@BenClarke .NET 4.5 вам понадобится хотя бы VS2012, чтобы использовать его. Если вы не можете пойти так высоко, я бы придерживался метода блокировки – BradleyDotNET

0

Код, который вы положили, уже делает именно это - вы создали свой WebClient, вы установите обработчик событий на свой завершенный метод и начнете загрузку. Если вы хотите подождать, пока он закончится, все, что вам нужно сделать, это позволить вашему методу закончить работу, и управление вернется к платформе Silverlight, которая будет вас ждать.

Другой способ сделать это - использовать ключевые слова async и await, которые, по-видимому, поддерживаются вашей инфраструктурой. Проще говоря, вы могли бы поставить ключевое слово await перед вызовом метода на DownloadStringAsync, что приведет к тому, что система дождитесь загрузки (и перейдет к другим задачам), вытащите строку после завершения загрузки и продолжите обычно:

string html = await webClient.DownloadStringAsync(address); 
+0

Спасибо за ваш ответ. Проблема в том, что мне нужно подождать сразу после 'webClient.DownloadStringAsync (адрес);', как показано ниже, для возврата URL-адреса.Ключевое слово ожидания, которое вы показали, не работает для меня im в VS2010 –

+0

Затем просто выполняйте запросы после того, как вы проанализируете их в своем обратном вызове. – TheHansinator

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