IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Utilisation de WebClient (attendre la fin du thread)


Sujet :

C#

  1. #1
    Membre éprouvé Avatar de scharly3
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Novembre 2008
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Novembre 2008
    Messages : 121
    Par défaut Utilisation de WebClient (attendre la fin du thread)
    Bonjour,

    J'ai actuellement une application [Silverlight] qui utilise WebClient afin d'accéder à un fichier XML.

    Ce fichier XML doit être charger au démarage de l'application car tout est basé sur sont contenu (mise en forme de l'appli/utilisation des données ...) or étant donnée que je fais appel à DownloadStringAsync l'application n'attend pas le chargement du fichier pour continuer ce qui la plante inévitablement.

    Ma question est comment attendre le résultat de DownloadStringAsync afin de continuer ?

    Voici mon code:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
     
    rivate string urlFile;
            private XElement sheets;
            public XmlFile()
            {
                UrlFile = "/Charts.xml";
                string host = (App.Current.Host.Source.AbsoluteUri).Substring(0, App.Current.Host.Source.AbsoluteUri.Length - App.Current.Host.Source.AbsolutePath.Length);
                TakeFileFromUri(host + UrlFile);
            }
            public void TakeFileFromUri(String URL)
            {
                Uri uri = new Uri(URL, UriKind.RelativeOrAbsolute);
                WebClient client = new WebClient();
                client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadStringCallback2);
                client.DownloadStringAsync(uri);
            }
            private void DownloadStringCallback2(Object sender, DownloadStringCompletedEventArgs e)
            {
                string resultBlock;
                if (e.Error == null)
                    resultBlock = e.Result;
                else
                    resultBlock = e.Error.ToString() + "erreur";
                XmlReader XmlFile = XmlReader.Create(new System.IO.StringReader(resultBlock));
                this.Sheets = XElement.Load(XmlFile);
     
            }
    Merci de votre aide

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Bah je comprends pas trop en fait... tu ne fais rien à la suite de TakeFileFromUri, donc il ne devrait plus rien se passer avant le DownloadStringCompleted ? Ou alors tu n'as pas mis le code complet...

  3. #3
    Membre éprouvé Avatar de scharly3
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Novembre 2008
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Novembre 2008
    Messages : 121
    Par défaut
    Bonjour Tom,

    En effet je n'ai pas mis le code complet, il manque les appelles à cet objet fait dans mon xaml.cs ainsi que les méthodes de l'objet XmlFile:


    Le xaml.cs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
           public LineChart()
            {
                InitializeComponent();
                this.initChart();
                this.filter();
                this.drawChart();
            }
            private void initChart()
            {
                //Telerik.Windows.Controls.Charting.EmptyPointBehavior
                XmlContentFile = new XmlFile();
                MyDataSource = XmlContentFile.getGridDataSource();
                this.LayoutRoot.Height = XmlContentFile.getContentHeight() + 25;
                this.LayoutRoot.Width = XmlContentFile.getContentWidth() + 10;
                this.radChart.Width = XmlContentFile.getContentWidth();
                this.radChart.Height = XmlContentFile.getContentHeight();
                this.radChart.DefaultView.ChartArea.SmartLabelsEnabled = true;
     
     
                this.radChart.DefaultView.ChartArea.AxisX.LabelRotationAngle = XmlContentFile.getLabelRotationAngle(); 
                myNodes = XmlContentFile.getSerieValues();
                //Source
                this.radChart.ItemsSource = MyDataSource;
                //Title
                this.radChart.DefaultView.ChartTitle.Content = XmlContentFile.getChartTitle();
                //Y axes
                radChart.DefaultView.ChartArea.AxisY.Title = XmlContentFile.getYaxesContent("yaxe1");
                if (XmlContentFile.getYaxesContent("yaxe2") != null)
                {
                    radChart.DefaultView.ChartArea.AxisY.Title = XmlContentFile.getYaxesContent("yaxe1");
                    AxisY axisY = new AxisY();
                    axisY.AxisName = "yaxe2";
                    axisY.Title = XmlContentFile.getYaxesContent("yaxe2");
                    radChart.DefaultView.ChartArea.AdditionalYAxes.Add(axisY);
                }
     
            }
    Les methodes du XmlFile sont du type:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
       public float getContentHeight()
            {
                //XElement sheets = XElement.Load(UrlFile);
                return float.Parse(Sheets.Attribute("height").Value);
            }
    Comme tu le constates les méthodes utilisent Sheets, qui est initialisé dans mon thread de lecture de fichier...

    Merci pour ton aide.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    OK... donc en fait, quand tu crées l'objet XmlFile, il faudrait que tu attendes qu'il soit "prêt" avant de commencer à l'utiliser.

    Par exemple, tu pourrais exposer dans XmlFile un évènement Loaded qui se déclenche quand le chargement est terminé. Et c'est seulement quand cet évènement se produirait que tu exécuterais la suite.

    Par contre, il vaudrait mieux que tu ne lances pas le chargement dans le constructeur de XmlFile : sinon il y a un risque que le chargement soit terminé avant que LineChart se soit abonné à l'évènement. Tu pourrais par exemple ajouter une méthode Load() sur XmlFile, qui lancerait le chargement. Et tu l'utiliserais comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
           public LineChart()
            {
                InitializeComponent();
     
                XmlContentFile = new XmlFile();
                XmlContentFile.Loaded += XmlContentFile_Loaded;
                XmlContentFile.Load()
            }
     
            private void XmlContentFile_Loaded(object sender, EventArgs e)
            {
                // Pour exécuter la méthode sur le thread de l'UI
                if (Dispatcher.CheckAccess())
                {
                    Dispatcher.Invoke(new EventHandler(XmlContentFile_Loaded), sender, e);
                    return;
                }
     
                this.initChart();
                this.filter();
                this.drawChart();
            }

  5. #5
    Membre éprouvé Avatar de scharly3
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Novembre 2008
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Novembre 2008
    Messages : 121
    Par défaut
    Merci encore pour tes réponses,

    En effet tu as très bien compris ma problèmatique.

    Citation Envoyé par tomlev
    tu pourrais exposer dans XmlFile un évènement Loaded qui se déclenche quand le chargement est terminé
    Pourais-tu illuster l'implémentation de l'évènement Loaded dans XmlFile ?

    Je trouve cela bien compliqué alors qu'il me suffirait d'avoir une méthode non-asynchrone pour n'avoir aucun problème je suis assez surpris d'avoir cette problèmatique.

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par scharly3 Voir le message
    tu pourrais exposer dans XmlFile un évènement Loaded qui se déclenche quand le chargement est terminé

    Pourais-tu illuster l'implémentation de l'évènement Loaded dans XmlFile ?
    Voilà :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
            public event EventHandler Loaded;
     
            private void OnLoaded()
            {
                EventHandler handler = Loaded;
                if (handler != null)
                    handler(this, EventArgs.Empty);
            }
     
            private void DownloadStringCallback2(Object sender, DownloadStringCompletedEventArgs e)
            {
                string resultBlock;
                if (e.Error == null)
                    resultBlock = e.Result;
                else
                    resultBlock = e.Error.ToString() + "erreur";
                XmlReader XmlFile = XmlReader.Create(new System.IO.StringReader(resultBlock));
                this.Sheets = XElement.Load(XmlFile);
     
                // Déclencher l'évènement
                OnLoaded();
     
            }

    Citation Envoyé par scharly3 Voir le message
    Je trouve cela bien compliqué alors qu'il me suffirait d'avoir une méthode non-asynchrone pour n'avoir aucun problème je suis assez surpris d'avoir cette problèmatique.
    Bah c'est le problème de Silverlight, tout doit être asynchrone pour pas bloquer l'UI... Mais tout ça deviendra plus simple avec C# 5

  7. #7
    Membre éprouvé Avatar de scharly3
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Novembre 2008
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Novembre 2008
    Messages : 121
    Par défaut
    Encore une fois merci pour le temps que tu prends pour m'aider.

    2 Problèmes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dispatcher.Invoke(new EventHandler(XmlContentFile_Loaded), sender, e);
    Me retourne :

    Erreur 1 'System.Windows.Threading.Dispatcher' ne contient pas une définition pour 'Invoke' et aucune méthode d'extension 'Invoke' acceptant un premier argument de type 'System.Windows.Threading.Dispatcher' n'a été trouvée (une directive using ou une référence d'assembly est-elle manquante ?) C:\Users\v-chsaug\Dropbox\ReportingSolution v0.3\ReportingSolution\Views\LineChart.xaml.cs 49 28 ReportingSolution
    Tu veux appeller: XmlFile.Load(), mais je n'ai pas de méthode .Load ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    XmlContentFile = new XmlFile();
                XmlContentFile.Loaded += XmlContentFile_Loaded;
                XmlContentFile.Load()

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par scharly3 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dispatcher.Invoke(new EventHandler(XmlContentFile_Loaded), sender, e);
    Me retourne :
    Ah oui, Silverlight n'a pas la méthode Invoke (j'utilise WPF d'habitude)...
    Utilise BeginInvoke à la place (même syntaxe à part ça)

    Citation Envoyé par scharly3 Voir le message
    Tu veux appeller: XmlFile.Load(), mais je n'ai pas de méthode .Load ?
    Il faut la créer et y mettre le code qui était dans le constructeur

  9. #9
    Membre éprouvé Avatar de scharly3
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Novembre 2008
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Novembre 2008
    Messages : 121
    Par défaut
    Bonjour,

    Me revoici à l'attaque

    J'ai bien appliqué toutes tes modifications mais cela ne semble pas fonctionner car je reste bloqué dans :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    if (Dispatcher.CheckAccess())
                {
                    Dispatcher.BeginInvoke(new EventHandler(XmlContentFile_Loaded), sender, e);
                    return;
                }
    Pourtant la méthode OnLoaded(); est bien appelée.

    Merci encore une fois pour votre support.

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par scharly3 Voir le message
    J'ai bien appliqué toutes tes modifications mais cela ne semble pas fonctionner car je reste bloqué dans :
    Comment ça tu "restes bloqué" ? Aucune de ces instructions n'est bloquante
    Il se passe quoi exactement quand tu exécutes en pas à pas ?

  11. #11
    Membre éprouvé Avatar de scharly3
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Novembre 2008
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Novembre 2008
    Messages : 121
    Par défaut
    Je suis pas bloqué a proprement parlé en effet, mais la méthode:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
            private void XmlContentFile_Loaded(object sender, EventArgs e)
            {
                // Pour exécuter la méthode sur le thread de l'UI
                if (Dispatcher.CheckAccess())
                {
                    Dispatcher.BeginInvoke(new EventHandler(XmlContentFile_Loaded), sender, e);
                    return;
                }
                this.initChart();
                this.filter();
                this.drawChart();
            }
    Et appelée sans que jamais this.initChart() ... soit executé.

    Pour rappel voici ou j'en suis

    Dans le xaml.cs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    public LineChart()
            {
                InitializeComponent();
                XmlContentFile = new XmlFile();
                XmlContentFile.Loaded += XmlContentFile_Loaded;
                XmlContentFile.load();
                //this.initChart();
                //this.filter();
                //this.drawChart();
            }
            private void XmlContentFile_Loaded(object sender, EventArgs e)
            {
                // Pour exécuter la méthode sur le thread de l'UI
                if (Dispatcher.CheckAccess())
                {
                    Dispatcher.BeginInvoke(new EventHandler(XmlContentFile_Loaded), sender, e);
                    return;
                }
                this.initChart();
                this.filter();
                this.drawChart();
            }
    Dans le XmlFile.cs

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
           public event EventHandler Loaded;
            public XmlFile()
            {
     
            }
            public void load()
            {
                UrlFile = "/Charts.xml";
                string host = (App.Current.Host.Source.AbsoluteUri).Substring(0, App.Current.Host.Source.AbsoluteUri.Length - App.Current.Host.Source.AbsolutePath.Length);
                TakeFileFromUri(host + UrlFile);
     
            }
            public void TakeFileFromUri(String URL)
            {
                Uri uri = new Uri(URL, UriKind.RelativeOrAbsolute);
                WebClient client = new WebClient();
                client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadStringCallback2);
                client.DownloadStringAsync(uri);
            }
            private void DownloadStringCallback2(Object sender, DownloadStringCompletedEventArgs e)
            {
                string resultBlock;
                if (e.Error == null)
                    resultBlock = e.Result;
                else
                    resultBlock = e.Error.ToString() + "erreur";
                XmlReader XmlFile = XmlReader.Create(new System.IO.StringReader(resultBlock));
                this.Sheets = XElement.Load(XmlFile);
                OnLoaded();
     
            }
            private void OnLoaded()
            {
                EventHandler handler = Loaded;
                if (handler != null)
                    handler(this, EventArgs.Empty);
            }

  12. #12
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Oops, désolé, en fait j'ai oublié un "not" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (!Dispatcher.CheckAccess())
    Ca devrait mieux marcher comme ça

  13. #13
    Membre éprouvé Avatar de scharly3
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Novembre 2008
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Novembre 2008
    Messages : 121
    Par défaut
    Voila qui Fonctionne Parfaitement !

    Citation Envoyé par tomlev Voir le message
    Oops, désolé, en fait j'ai oublié un "not" :
    Je ne pense pas qu'il te sois nécessaire de t'excuser alors qu'en bonne assisté, j'aurais pu / du trouver l'erreur par moi même ...

    Merci encore pour ton aide !

  14. #14
    Membre émérite Avatar de kheironn
    Homme Profil pro
    Chef de projets technique C# / MVC / .Net
    Inscrit en
    Février 2007
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets technique C# / MVC / .Net
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2007
    Messages : 822
    Par défaut
    Citation Envoyé par scharly3 Voir le message
    Voila qui Fonctionne Parfaitement !


    Je ne pense pas qu'il te sois nécessaire de t'excuser alors qu'en bonne assisté, j'aurais pu / du trouver l'erreur par moi même ...

    Merci encore pour ton aide !
    Ben justement, un bon assisté ne peut pas la trouver...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Multi thread] Attendre la fin des threads
    Par rvzip64 dans le forum Langage
    Réponses: 4
    Dernier message: 12/05/2015, 10h53
  2. [thread]attendre la fin d'un thread?....
    Par babarpapa dans le forum Concurrence et multi-thread
    Réponses: 9
    Dernier message: 29/03/2006, 14h31
  3. [Thread] Attendre la fin ...
    Par phplive dans le forum Langage
    Réponses: 2
    Dernier message: 21/03/2006, 22h29
  4. Attendre la fin des threads fils d'un processus
    Par SteelBox dans le forum Windows
    Réponses: 15
    Dernier message: 24/02/2006, 16h08
  5. [Thread] comment attendre la fin d'un thread?
    Par billynirvana dans le forum Concurrence et multi-thread
    Réponses: 11
    Dernier message: 24/08/2005, 10h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo