2014-02-07 3 views
1

Я делаю веб-запрос с DownloadStringAsync(), но мне нужно вернуть результат только при вызове события DownloadStringCompleted. После метода downloadasync мне нужно дождаться результата, а затем я могу вернуть его в свойство string. Поэтому я внедрил while(Result == ""), но я не знаю, что там делать. Я уже пробовал Thread.sleep(500), но кажется, что загрузка так и не завершилась. И код остается в то время навсегда.Ожидание и возврат результата с помощью DownloadStringAsync WP8

string Result = ""; 

    public String Query(DataRequestParam dataRequestParam) 
    {  
     try 
     { 
      WebClient web = new WebClient(); 

      if (!string.IsNullOrEmpty(dataRequestParam.AuthentificationLogin)) 
      { 
       System.Net.NetworkCredential account = new NetworkCredential(dataRequestParam.AuthentificationLogin, dataRequestParam.AuthentificationPassword); 
       web.Credentials = account; 
      } 

      web.DownloadStringCompleted += OnDownloadStringCompleted; 
      web.DownloadStringAsync(dataRequestParam.TargetUri); 

      while (Result == "") 
      { 
       //What am i supposed to do here ? 
      } 
      return Result; 
     }  
     catch(WebException we) 
     { 
      MessageBox.Show(we.Message); 
      return null; 
     } 
    } 

    private void OnDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) 
    { 
     if (e.Error != null) 
     { 
      //Error treating 
     } 
     else 
     { 
      Result = e.Result; 
     } 
    } 

КОД UI

protected override void OnNavigatedTo(NavigationEventArgs e) 
    { 
    base.OnNavigatedTo(e); 


    if (e.NavigationMode != NavigationMode.Back) 
    { 

    ServerFunctions.SetUserProfil(User.UserLogin,User.UserPassword); 

    this.listBoxGetDocsLibs.Clear(); 
    List<BdeskDocLib> list = new List<BdeskDocLib>(); 
    try 
    { 
     //HERE THE START OF THE DOWNLOAD 
     ServerFunctions.GetDocLibs(true); 
    } 
    catch (Exception ex) 
    { 
     //error 
    } 

    foreach (BdeskDocLib docLib in list) 
    { 
     this.listBoxGetDocsLibs.Add(docLib); 
    } 

    } 

} 

ServerFunction статический класс

public static List<BdeskDocLib> GetDocLibs(bool onlyDocLibPerso) 
    { 
     string xmlContent = GetXml(URL_GETDOCLIBS); 
     List<BdeskDocLib> result = BdeskDocLib.GetListFromXml(xmlContent, onlyDocLibPerso); 
     return result; 
    } 

    private static String GetXml(string partialUrl) 
    { 

     string url = GenerateUrl(partialUrl); 

     DataRequestParam dataRequestParam = new DataRequestParam(); 
     dataRequestParam.TargetUri = new Uri(url); 
     dataRequestParam.UserAgent = "BSynchro"; 

     dataRequestParam.AuthentificationLogin = userLogin; 
     dataRequestParam.AuthentificationPassword = userPwd; 

     //HERE I START THE QUERY method 
     // NEED QUERY RETURNS A STRING or Task<String> 
     DataRequest requesteur = new DataRequest(); 
     xmlResult=requesteur.Query(dataRequestParam); 


     if (CheckErrorConnexion(xmlResult) == false) 
     { 
      throw new Exception("Erreur du login ou mot de passe"); 
     } 

     return xmlResult; 
    } 
+1

Вы видели [этот вопрос SO] (http://stackoverflow.com/questions/5071076/downloadstringasync-wait-for-request-completion)? Это звучит как твоя проблема для меня, не так ли? –

+0

да, я уже видел этот вопрос, но это не помогло мне, потому что мне нужно сделать результат результата тем же методом, который вызвал метод DownloadStringAsync(): Query() ... результат будет обработан в другой класс ... Я также попытался использовать DownloadStringTaskAsync, но, похоже, у меня есть тупик, я разместил здесь вопрос об этом [ссылка] (http://stackoverflow.com/questions/21606017/task-status-waiting-for- activation-downloadstringtaskasync-wp8) –

ответ

0

Там нет ничего хорошего в блокировании основного пользовательского интерфейса (если вы действительно не нужны). Но если вы хотите, чтобы ждать вашего результата вы можете сделать некоторые использование асинхронного-ОЖИДАНИЯ и TaskCompletitionSource - вы можете найти more about on this blog и how to use TCS in this answer:

public static Task<string> myDownloadString(DataRequestParam dataRequestParam) 
{ 
    var tcs = new TaskCompletionSource<string>(); 
    var web = new WebClient(); 

    if (!string.IsNullOrEmpty(dataRequestParam.AuthentificationLogin)) 
    { 
     System.Net.NetworkCredential account = new NetworkCredential(dataRequestParam.AuthentificationLogin, dataRequestParam.AuthentificationPassword); 
     web.Credentials = account; 
    } 

    web.DownloadStringCompleted += (s, e) => 
    { 
     if (e.Error != null) tcs.TrySetException(e.Error); 
     else if (e.Cancelled) tcs.TrySetCanceled(); 
     else tcs.TrySetResult(e.Result); 
    }; 

    web.DownloadStringAsync(dataRequestParam.TargetUri); 
    return tcs.Task; 
} 



public async Task<string> Query(DataRequestParam dataRequestParam) 
{ 
    string Result = ""; 
    try 
    { 
     Result = await myDownloadString(dataRequestParam); 
    } 
    catch (WebException we) 
    { 
     MessageBox.Show(we.Message); 
     return null; 
    } 
    return Result; 
} 

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

+0

Мне нужно, чтобы метод query() возвращал мой результат, потому что я вызываю этот метод в другом классе, в котором я обрабатываю результат. В вашем примере возврат запроса mehtod недействителен ... –

+0

@ PaulMartinez вы можете изменить его как хотите (на мой взгляд, этот метод запроса больше не нужен - вы можете вызвать myDonload непосредственно из своего класса). Помните, что этот метод является асинхронным, и если вы хотите дождаться его, вы должны сделать mystring = wait Query(); – Romasz

+0

Хорошо, поэтому я попробовал ваш код, и я поддержал ту же проблему, что и я опубликовал здесь [LINK] (http://stackoverflow.com/questions/21606017/task-status-waiting-for-activation-downloadstringtaskasync-wp8) Возврат mydownloadstring задача и ее статус - «Ожидание активации». Так что в режиме отладки, когда mydownloadString заканчивается и код возвращается в методе Query, пользовательский интерфейс моего приложения всплывает и остается заблокированным. Нет ошибки ... –

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