locked
Meilleur moyen pour executer plusieurs requêtes http RRS feed

  • Question

  • Bonjour,

    Pour m'entrainer au développement Windows phone j'essaye de faire une application de lecture de petites actus provenant d'un fichier xml sur serveur.

    Je souhaite sauvegarder ce ficher en local uniquement lorsqu'une nouvelle version par rapport a celle du mobile est disponible. Pour savoir si une maj est disponible j'ai une url avec un md5 qui me permet de vérifier.

    Il me faut donc au lancement de l'application exécuter un première requête pour vérifier si une nouvelle version est disponible. Selon ce résultat je récupère le fichier xml.

    Ma question est avec quelle moyen le plus propre possible je peut exécuter les requêtes. Car si j'utilise ce code :

    WebClient webClient = new WebClient();
                webClient.DownloadStringCompleted += HttpCompleted;

    Je vais devoir en faire un "HttpCompleted" pour chaque requête.

    Existe t-il un moyen de récupérer simplement mon md5 sans un listener

    Merci

    lundi 19 janvier 2015 09:00

Réponses

  • En fait, il y a 3 erreurs dans votre code:

    1 : il faut s'abonner à l'événement avant d'appeler la méthode "DownLoadStringAsync" car c'est cette dernière qui va appeler l'événement "DownloadStringCompleted" auquel vous vous êtes abonné avec l'expression lambda.

    2 : La signature de l'événement où il faut s'abonner ne renvoie rien, donc il ne faut pas y mettre de "return true".

    3 : alors la dernière erreur est due au fait que Microsoft n'ont pas tout à fait bien respecté leur nomenclature : en fait il faut appeler la méthode "DownloadStringTaskAsync" et non pas "DownloadStringAsync". En effet, "DownloadStringAsync" ne renvoie pas d'objet "Task", du coup impossible d'attendre avec await.

    Ce qu'il aurait fallu faire, à mon avis c'est :

    private async Task<bool> CheckIfUpdateAvailable()
            {
                WebClient webClientCheck = new WebClient();
                webClientCheck.DownloadStringCompleted += (snd, evt) =>
                {
                    string md5Result = evt.Result;
                };
    string result = await webClientCheck.DownloadStringTaskAsync(new Uri("http://backoffice.optin-r.com/fr/flux/bn?id=6&title=1&day=15&key=1"));
    
               return true;
            }

    L'abonnement à "DownloadStringCompleted" n'est pas indispensable et peut servir en cas d'erreur...

    Idéalement, il aurait peut-être même fallu faire ainsi peut-être :

    private async Task<bool> CheckIfUpdateAvailable()
            {
                WebClient webClientCheck = new WebClient();
    try
    {
    string result = await webClientCheck.DownloadStringTaskAsync(new Uri("http://backoffice.optin-r.com/fr/flux/bn?id=6&title=1&day=15&key=1"));
    }
    catch(WebException exc)
    {
       return false;
    }
    
    return true;
    }


    Philippe

    • Marqué comme réponse Florian R SAS jeudi 22 janvier 2015 16:02
    lundi 19 janvier 2015 16:04

Toutes les réponses

  • Rebonjour Florian,

    En effet, s'abonner à l'événement "DownloadStringCompleted" est bien mais vous n'êtes pas obligé de déclarer une fonction "HttpCompleted" à chaque fois. Si vraiment il s'agit d'une fonction qui sera spécifique, alors vous pouvez utiliser une expression lambda. Il s'agit en fait de "fonctions déclarées à la volée" qui sont accessibles uniquement dans la portée où elles sont déclarées. Cela peut être notamment une méthode.

    Par exemple, pour votre code, cela donnerait :

    WebClient webClient = new WebClient();
                webClient.DownloadStringCompleted += (snd,evt) =>
    {
      //Le corps de l'expression lambda, où snd est l'objet et evt l'argument...
    };
    N'hésitez pas à regarder la documentation MSDN concernant les expressions lambda...


    Philippe

    lundi 19 janvier 2015 14:59
  • Merci Philippe,

    Je vais donc utiliser cela.

    Une dernière question si je copie colle le même code en dessous pour une deuxième requête différente est-ce qu'il sera exécuté lorsque ma première requête sera terminée ?

    Merci


    Florian R SAS

    lundi 19 janvier 2015 15:09
  • Alors il faut faire attention car le fait de s'abonner à "DownloadStringCompleted" ne va pas lancer le téléchargement... C'est là qu'il faut appeler les méthodes qui renvoient des tâches et les appeler avec des "await". Le fait d'appeler avec "await" va garantir le fait que la seconde requête que vous souhaitez appeler sera bien exécutée après la première requête, et tout cela sans bloquer l'IHM.

    WebClient webClient = new WebClient();
                webClient.DownloadStringCompleted += (snd,evt) =>
    {
      //Le corps de l'expression lambda, où snd est l'objet et evt l'argument...
    };
    
    string chaineRecue = await webClient.DownloadStringTaskAsync(new Uri("http://www.lesite.com"));
    
    //Si un pb a eu lieu ici, ce sera l'expression lambda abonnée à "DownloadStringCompleted" qui va le dire dans son arguement, bien penser à consulter la doc MSDN de cet événement...

    Bien entendue, la méthode qui appelle tout cela doit être marquée "async" (et comme je le disais dans l'autre thread, cela ne posera pas de problème s'il s'agit d'une méthode abonnée à un clic de bouton par exemple ou alors un événement de type chargement "Load")...


    Philippe

    lundi 19 janvier 2015 15:21
  • Je suis un peut perdu....

    Voilà mon code :

            async protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
            {
    
                base.OnNavigatedTo(e);
    
                await CheckIfUpdateAvailable();
    }
    
    private async Task<bool> CheckIfUpdateAvailable()
            {
                WebClient webClientCheck = new WebClient();
                webClientCheck.DownloadStringAsync(new Uri("http://backoffice.optin-r.com/fr/flux/bn?id=6&title=1&day=15&key=1"));
                webClientCheck.DownloadStringCompleted += (snd, evt) =>
                {
                    string md5Result = evt.Result;
    
                    return true;
                };
            }

    mon compileur me souligne mon "return true"

    Je voit mon erreur, je ne peut pas faire de return à partir du DownloadStringCompleted

    mais comment le faire ?


    Florian R SAS


    lundi 19 janvier 2015 15:51
  • En fait, il y a 3 erreurs dans votre code:

    1 : il faut s'abonner à l'événement avant d'appeler la méthode "DownLoadStringAsync" car c'est cette dernière qui va appeler l'événement "DownloadStringCompleted" auquel vous vous êtes abonné avec l'expression lambda.

    2 : La signature de l'événement où il faut s'abonner ne renvoie rien, donc il ne faut pas y mettre de "return true".

    3 : alors la dernière erreur est due au fait que Microsoft n'ont pas tout à fait bien respecté leur nomenclature : en fait il faut appeler la méthode "DownloadStringTaskAsync" et non pas "DownloadStringAsync". En effet, "DownloadStringAsync" ne renvoie pas d'objet "Task", du coup impossible d'attendre avec await.

    Ce qu'il aurait fallu faire, à mon avis c'est :

    private async Task<bool> CheckIfUpdateAvailable()
            {
                WebClient webClientCheck = new WebClient();
                webClientCheck.DownloadStringCompleted += (snd, evt) =>
                {
                    string md5Result = evt.Result;
                };
    string result = await webClientCheck.DownloadStringTaskAsync(new Uri("http://backoffice.optin-r.com/fr/flux/bn?id=6&title=1&day=15&key=1"));
    
               return true;
            }

    L'abonnement à "DownloadStringCompleted" n'est pas indispensable et peut servir en cas d'erreur...

    Idéalement, il aurait peut-être même fallu faire ainsi peut-être :

    private async Task<bool> CheckIfUpdateAvailable()
            {
                WebClient webClientCheck = new WebClient();
    try
    {
    string result = await webClientCheck.DownloadStringTaskAsync(new Uri("http://backoffice.optin-r.com/fr/flux/bn?id=6&title=1&day=15&key=1"));
    }
    catch(WebException exc)
    {
       return false;
    }
    
    return true;
    }


    Philippe

    • Marqué comme réponse Florian R SAS jeudi 22 janvier 2015 16:02
    lundi 19 janvier 2015 16:04