Partage
  • Partager sur Facebook
  • Partager sur Twitter

Fichier images long à charger

Sujet résolu
    18 mai 2021 à 3:27:27

    Bonjour voici mon code

    private string DownloadSourceCode(string url)
            {
                string sourceCode = "";
                try
                {
                    using (WebClient WC = new WebClient())
                    {
                        WC.Encoding = Encoding.UTF8;
                        WC.Headers.Add("Accept", "image / webp, */*");
                        WC.Headers.Add("Accept-Language", "fr, fr - FR");
                        WC.Headers.Add("Cache-Control", "max-age=1");
                        WC.Headers.Add("DNT", "1");
                        WC.Headers.Add("Origin", url);
                        WC.Headers.Add("TE", "Trailers");
                        WC.Headers.Add("user-agent", Fichier.LoadUserAgent());
                        sourceCode = WC.DownloadString(url);
                    }
                }
                catch (WebException e)
                {
                    if (e.Status == WebExceptionStatus.ProtocolError)
                    {
                        string status = string.Format("{0}", ((HttpWebResponse)e.Response).StatusCode);
                        LabelID.TextInvoke(string.Format("{0} {1} {2} ", status,
                                                        ((HttpWebResponse)e.Response).StatusDescription,
                                                        ((HttpWebResponse)e.Response).Server));
                        
                    }
                }
                catch (NotSupportedException a) { MessageBox.Show(a.Message); }
                return sourceCode;
            }
    
            private void DownloadImage(string URL, string filePath)
            {
                try
                {
                    using (WebClient WC = new WebClient())
                    {
                        WC.Encoding = Encoding.UTF8;
                        WC.Headers.Add("Accept", "image / webp, */*");
                        WC.Headers.Add("Accept-Language", "fr, fr - FR");
                        WC.Headers.Add("Cache-Control", "max-age=1");
                        WC.Headers.Add("DNT", "1");
                        WC.Headers.Add("Origin", "https://myprivatesite.fr//" + STARTNBR.ToString());
                        WC.Headers.Add("user-agent", Fichier.LoadUserAgent());
                        WC.DownloadFile(URL, filePath);
                        NBRIMAGESDWLD++;
                    }
                    STARTNBR = CheckBoxBack.Checked ? --STARTNBR : ++STARTNBR;
                }
                catch (IOException)
                {
                    LabelID.TextInvoke("Accès non autorisé au fichier");
                }
                catch (WebException e) 
                {
                    if (e.Status == WebExceptionStatus.ProtocolError)
                    {
                        LabelID.TextInvoke(string.Format("{0} / {1} / {2} ", ((HttpWebResponse)e.Response).StatusCode,
                                                                            ((HttpWebResponse)e.Response).StatusDescription,
                                                                            ((HttpWebResponse)e.Response).Server));
                    }
                }
                catch (NotSupportedException a) { MessageBox.Show(a.Message); }
            }
    
            private void DownloadImages()
            {
                const string URL = "https://myprivatesite.fr/";
    
                string imageIDURL = string.Concat(URL, STARTNBR);
    
                string sourceCode = DownloadSourceCode(imageIDURL);
                if (sourceCode != string.Empty)
                {
                    string imageNameURL = Fichier.GetURLImage(sourceCode);
                    if (imageNameURL != string.Empty)
                    {
                        string imagePath = PATHIMAGES + STARTNBR + ".png";
                        LabelID.TextInvoke(STARTNBR.ToString());
                        LabelImageURL.TextInvoke(imageNameURL + "\r");
                        DownloadImage(imageNameURL, imagePath);
                        Extension.SaveOptions(STARTNBR, CheckBoxBack.Checked);
                    }
                }
                STARTNBR = CheckBoxBack.Checked ? --STARTNBR : ++STARTNBR;
            }
    
            // END FUNCTIONS
    
            private void BoutonStartPause_Click(object sender, EventArgs e)
            {
                if (Fichier.RGBIMAGES != null)
                {
                    if (boutonStartPause.Text == "Start")
                    {
                        boutonStartPause.ForeColor = Color.DarkRed;
                        boutonStartPause.Text = "Pause";
                        if (myTimer == null)
                            myTimer = new System.Threading.Timer(_ => new Task(DownloadImages).Start(), null, 0, Trackbar.Value);
                    }
                    else if (boutonStartPause.Text == "Pause")           
                        EndTimer();
    
                    Extension.SaveOptions(STARTNBR, CheckBoxBack.Checked);
                }
            }

    Le problème que je rencontre est que, j'ai essayé de telecharger 1000+ images, cela fonctionne mais, il faut un très long temps d'attente pour que l'image se charge complètement or le programme passe à la suivante et ainsi de suite jusqu'à admettons 100 mais la 8ème image n'est toujours pas fini de se télécharger. Du coup j'aimerais comprendre pourquoi svp je rencontre un tel problème ici et/ou comment palier ce problème
    Merci d''avance..

    -
    Edité par hugoducine 18 mai 2021 à 3:46:15

    • Partager sur Facebook
    • Partager sur Twitter
      18 mai 2021 à 14:31:16

      Vous avez "sciemment" fait en sorte que le chargement des images soient asynchrone, et le téléchargement d'un fichier via HTTP n'a jamais été instantané.

      Le comportement observé est cohérent avec le code. Si vous ne voulez pas continuer l'exécution de votre code tant que les images ne soit pas téléchargées, utilisez des primitives synchrones ou utilisez l'évènement de fin de chargement pour y faire ce que vous voulez faire après la fin du téléchargement.

      • Partager sur Facebook
      • Partager sur Twitter
      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
        18 mai 2021 à 17:08:14

        bacelar a écrit:

        Vous avez "sciemment" fait en sorte que le chargement des images soient asynchrone, et le téléchargement d'un fichier via HTTP n'a jamais été instantané.

        Le comportement observé est cohérent avec le code. Si vous ne voulez pas continuer l'exécution de votre code tant que les images ne soit pas téléchargées, utilisez des primitives synchrones ou utilisez l'évènement de fin de chargement pour y faire ce que vous voulez faire après la fin du téléchargement.


        Oui c'est vrai désolé, je vous ai donnée l'ancienne version de mon code, je n'ai pas fait attention. Et oui ça n'a jamais été instantané mais de là, à attendre plus de 5m pour une image alors que le programme en est déjà à la 100éme, il y a un problème. J'ai essayé de télécharger un gros fichier du genre 700mo cela à fonctionner et il a fallu moins de 3m pour le télécharger correctement.

        Je vais me renseigner car c'est la première fois que j'utilise les Thread, comme toute nouvelle chose c'est compliqué au début !

        Mais du coup, voici ma nouvelle version du code et j'ai utilisé les évènements de fin comme vous dites, mais le problème reste le même:

                    private void DownloadSourceCode()
                    {
                        try
                        {
                            string URL = "https://myprivatesite.fr//" + STARTNBR;
                            using (WebClient WC = new WebClient())
                            {
                                WC.Encoding = Encoding.UTF8;
                                WC.Headers.Add("Accept", "image / webp, */*");
                                WC.Headers.Add("Accept-Language", "fr, fr - FR");
                                WC.Headers.Add("Cache-Control", "max-age=1");
                                WC.Headers.Add("DNT", "1");
                                WC.Headers.Add("Origin", URL);
                                WC.Headers.Add("user-agent", Fichier.LoadUserAgent());
                                WC.DownloadStringCompleted += new DownloadStringCompletedEventHandler(StringCompleted);
                                WC.DownloadStringAsync(new Uri(URL));
                            }
        
                        }
                        catch (WebException e)
                        {
                            if (e.Status == WebExceptionStatus.ProtocolError)
                            {
                                LabelID.TextInvoke(string.Format("{0} {1} {2}", ((HttpWebResponse)e.Response).StatusCode,
                                    ((HttpWebResponse)e.Response).StatusDescription,
                                    ((HttpWebResponse)e.Response).Server));
        
                            }
                        }
                        catch (NotSupportedException a) { MessageBox.Show(a.Message); }
        
                    }
        
        
                    private void StringCompleted(object s, DownloadStringCompletedEventArgs e)
                    {
                        string sourceCode = e.Result;
        
                        if (sourceCode != string.Empty)
                        {
                            string imageNameURL = Fichier.GetURLImage(sourceCode);
                            if (imageNameURL != string.Empty)
                            {
                                string imagePath = PATHIMAGES + STARTNBR.ToString() + ".png";
                                LabelID.TextInvoke(STARTNBR.ToString());
                                LabelImageURL.TextInvoke(imageNameURL + "\r");
                                DownloadImage(imageNameURL, imagePath);
                                Extension.SaveOptions(STARTNBR, CheckBoxBack.Checked);
                            }
                        }
                        STARTNBR = CheckBoxBack.Checked ? --STARTNBR : ++STARTNBR;
                    }
        
        
                    private void DownloadImage(string URL, string filePath)
                    {
                        try
                        {
                            using (WebClient WC = new WebClient())
                            {
                                WC.Encoding = Encoding.UTF8;
                                WC.Headers.Add("Accept", "image / webp, */*");
                                WC.Headers.Add("Accept-Language", "fr, fr - FR");
                                WC.Headers.Add("Cache-Control", "max-age=1");
                                WC.Headers.Add("DNT", "1");
                                WC.Headers.Add("Origin", "https://myprivatesite.fr//" + STARTNBR);
                                WC.Headers.Add("user-agent", Fichier.LoadUserAgent());
                                WC.DownloadFileAsync(new Uri(URL), filePath);
                            }
                        }
                        catch (IOException)
                        {
                            LabelID.TextInvoke("Accès non autorisé au fichier");
                        }
                        catch (WebException e)
                        {
                            if (e.Status == WebExceptionStatus.ProtocolError)
                            {
                                LabelID.TextInvoke(string.Format("{0} / {1} / {2} ", ((HttpWebResponse)e.Response).StatusCode,
                                    ((HttpWebResponse)e.Response).StatusDescription,
                                    ((HttpWebResponse)e.Response).Server));
                            }
                        }
                        catch (NotSupportedException a) { MessageBox.Show(a.Message); }
                    }
        
                    private void DownloadDataCompleted(object s, DownloadDataCompletedEventArgs a)
                    {
                        try
                        {
                            Fichier.SaveBitmap(Fichier.ByteToBitmap(a.Result), PATHIMAGES + STARTNBR + ".png");
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show(a.Error + " / " + e.Message);
                        }
                    }
        
                    // END FUNCTIONS
        
                    private void BoutonStartPause_Click(object sender, EventArgs e)
                    {
                        if (Fichier.RGBIMAGES != null)
                        {
                            if (boutonStartPause.Text == "Start")
                            {
                                boutonStartPause.ForeColor = Color.DarkRed;
                                boutonStartPause.Text = "Pause";
                                if (myTimer == null)
                                    myTimer = new System.Threading.Timer(_ =>  DownloadSourceCode(), null, 0, Trackbar.Value);
                                else
                                    myTimer.Change(0, Trackbar.Value);
                            }
                            else if (boutonStartPause.Text == "Pause")
                                EndTimer();
        
                            Extension.SaveOptions(STARTNBR, CheckBoxBack.Checked);
                        }
                    }

        Au niveau du DownloadFile, j'ai déjà essayé avec

        WC.DownloadDataCompleted += new DownloadDataCompletedEventHandler(DownloadDataCompleted);
                            WC.DownloadDataAsync(new Uri(URL));

        Le problème reste le même, j'ai essayé de mille façon d'écrire ce programme mais ça revient toujours pareil, sauf si j'enlève Async aux fonctions DownloadString et DownloadData ou DownloadFile, cela va bien attendre que le fichier se termine mais alors là problème... Pour une seule image le programme mets 1 à 3m pour la télécharger, du coup je suis un peu perdu là..

        • Partager sur Facebook
        • Partager sur Twitter
          19 mai 2021 à 11:33:07

          si c'est toujours la même image qui pose souci, regarde ce qu'elle a de particulier
          • Partager sur Facebook
          • Partager sur Twitter
            21 mai 2021 à 12:35:19

            Vous êtes sûr de ne pas vous prendre une protection anti DDOS dans les dents ???
            • Partager sur Facebook
            • Partager sur Twitter
            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
              21 mai 2021 à 17:40:44

              umfred a écrit:

              si c'est toujours la même image qui pose souci, regarde ce qu'elle a de particulier

              Non c'est le cas pour toutes :/

              bacelar a écrit:

              Vous êtes sûr de ne pas vous prendre une protection anti DDOS dans les dents ???

              Non plus, mais j'ai trouvé la solution grâce à un autre forum comme celui-ci.

              Le truc qui pouvait causer ça c'est soit:

              - Connexion/épuisements des ports:

              Le truc c'est que dès qu'on utilise un WebClient, les ressources qu'il utilise ne sont parfois pas libérées immédiatement et ça provoque un délai entre le moment où cet objet est supprimé et le moment où le prochain WebClient tente d'utiliser le même port / la connexion.

              Et donc il est possible qu'au moment où le prochain WebClient soit instancié, le port que le dernier utilisait ne soit pas encore disponible, entraînant un retard (pendant qu'il attend le port) ou pire le prochain WebClient ouvrant un autre port. Cela peut provoquer l'ouverture d'une liste interminable de connexions, entraînant l'arrêt des choses

              ou

              - Épuisement ThreadPool

              Cela est dû à la tentative de créer trop d'objets Task ou Thread à la fois qui bloquent leur propre exécution (via Thread.Sleep ou une opération de longue durée). Normalement, ce n'est pas un problème puisque le TaskScheduler intégré fait un très bon travail de suivi de nombreuses tâches et s'assure qu'ils ont tous à tour de rôle pour exécuter leur code. Là où cela devient un problème, le TaskScheduler n'a pas de contexte pour lequel les tâches sont importantes, ou quelles tâches vont nécessiter plus de temps que d'autres pour être achevées. Ainsi, lorsque de nombreuses tâches traitent des opérations de longue durée, bloquent ou lancent des exceptions, le TaskScheduler doit attendre la fin de ces tâches avant de pouvoir en démarrer de nouvelles. Si vous êtes particulièrement malchanceux, le TaskScheduler peut démarrer un tas de tâches qui sont toutes bloquantes et aucune tâche ne peut démarrer, même si toutes les autres tâches en attente sont petites et se termineraient instantanément.

              Donc ce fait, utiliser le moins de tâches possible pour augmenter la fiabilité et éviter l'épuisement du ThreadPool

              Maintenant pour ceux qui ont le même problème que moi, voici mon code

              private static readonly Fichiers Fichier = new Fichiers();
                      public static int MaxConcurrentDownloads => Environment.ProcessorCount;
                      private static readonly ConcurrentDictionary<string, WebClient> Clients;
                      public static readonly SemaphoreSlim Locker;
                      private static CancellationTokenSource TokenSource = new CancellationTokenSource();
              
                      static ConcurrentWebClient()
                      {
                          Clients = new ConcurrentDictionary<string, WebClient>();
              
                          if (Locker is null)
                              Locker = new SemaphoreSlim(MaxConcurrentDownloads, MaxConcurrentDownloads);
                      }
              
                      private async Task<WebClient> CreateClient(string Name, bool persistent, CancellationToken token)
                      {
                          if (Clients.ContainsKey(Name))
                          {
                              return Clients[Name];
                          }
              
                          WebClient newClient = new WebClient();
              
                          if (persistent)
                          {
                              while (Clients.TryAdd(Name, newClient) is false)
                              {
                                  token.ThrowIfCancellationRequested();
                                  await Task.Delay(1, token);
                              }
                          }
              
                          return newClient;
                      }
              
                      public async Task<T> NewRequest<T>(Func<WebClient, T> Expression, int? MaxTimeout = null, string Id = null)
                      {
                          await Locker.WaitAsync(MaxTimeout ?? 100_000, TokenSource.Token);
              
                          bool persistent = true;
                          if (Id is null)
                          {
                              persistent = false;
                              Id = string.Empty;
                          }
              
                          try
                          {
                              WebClient client = await CreateClient(Id, persistent, TokenSource.Token);
                              T result = await Task.Run<T>(() => Expression(client), TokenSource.Token);
              
                              if (persistent is false)
                                  client?.Dispose();
              
                              return result;
                          }
                          finally
                          {
                              Locker.Release();
                          }
                      }
              
                      public void AssignDefaultHeaders(WebClient client)
                      {
                          client.Encoding = Encoding.UTF8;
                          client.Headers.Add("Accept", "image / webp, */*");
                          client.Headers.Add("Accept-Language", "fr, fr - FR");
                          client.Headers.Add("Cache-Control", "max-age=1");
                          client.Headers.Add("DNT", "1");
              
                          client.Headers.Add("user-agent", Fichier.LoadUserAgent());
                      }
              
                      public async Task Cancel(string Name)
                      {
                          if (Clients.ContainsKey(Name))
                          {
                              CancellationToken token = TokenSource.Token;
                              WebClient foundClient;
              
                              while (Clients.TryGetValue(Name, out foundClient) is false)
                              {
                                  token.ThrowIfCancellationRequested();
                                  await Task.Delay(1, token);
                              }
              
                              if (foundClient != null)
                              {
                                  foundClient?.CancelAsync();
                                  foundClient?.Dispose();
                              }
                          }
                      }
              
                      public void ForceCancelAll()
                      {
                          TokenSource?.Cancel();
                          TokenSource?.Dispose();
                          TokenSource = new CancellationTokenSource();
              
                          foreach (var item in Clients)
                          {
                              item.Value?.CancelAsync();
                              item.Value?.Dispose();
                          }
              
                          Clients.Clear();
                      }
                      private async Task<string[]> DownloadSourceCode()
                      {
                          var downloader = new ConcurrentWebClient();
                          return await downloader.NewRequest<string[]>((WebClient client) =>
                          {
                              const string website = "http://www.myprivatesite.fr/";
                              const int max = 250;
                              string[] sourceCodes = new string[max];
                              for (int i = 0; i < max; i++)
                              {
                                  string url = website +STARTNBR + (UInt64)i;
              
                                  downloader.AssignDefaultHeaders(client);
                                  client.Headers.Add("Origin", url);
              
                                  string source = client.DownloadString(url);
                                  if (!Fichier.ContainsBOT(source))
                                      sourceCodes[i] = Fichier.GetURLImage(source);
                                  else
                                      sourceCodes[i] = string.Empty;
                              }
                              return sourceCodes;
                          });
                      }
              
                      private async Task<bool> DownloadImage(string[] UrlImages)
                      {
                          var downloader = new ConcurrentWebClient();
              
                          bool downloadsSucessful = await downloader.NewRequest<bool>((WebClient client) =>
                          {
                              int length = UrlImages.Length;
                              downloader.AssignDefaultHeaders(client);
                              for (int i = 0; i < length; i++, STARTNBR++)
                              {
                                  if (UrlImages[i] != string.Empty)
                                  {
                                      string base36 = Extension.EncodeBase36ToString(STARTNBR).ToUpper();
                                      LabelID.TextInvoke(base36);
                                      LabelImageURL.TextInvoke(UrlImages[i]);
                                      LabelFichiersDwld.TextInvoke((++NBRIMAGESDWLD).ToString() +
                                                                  " image(s) téléchargé(s)");
              
                                      const string originHeader = "http://www.myprivatesite.fr/";
                                      client.Headers.Add("Origin", originHeader);
              
                                      string imagePath = PATHIMAGES + STARTNBR + ".png";
                                      client.DownloadFile(UrlImages[i], imagePath);
                                  }
                              }
                              return true;
                          });
              
                          return downloadsSucessful;
                      }
              
              
                      bool IsRunning = false;
                      private async void StartDownload()
                      {
                          while (IsRunning )
                          {
                              string[] imageIDURL = null;
                              await Task.Run(() => { imageIDURL = DownloadSourceCode().Result; });
              
                              bool isok = false;
                              await Task.Run(() => { isok = DownloadImage(imageIDURL).Result; });
                              Extension.SaveOptions(STARTNBR, CheckBoxBack.Checked);
                          }
                          
                      }

              -
              Edité par hugoducine 21 mai 2021 à 18:10:12

              • Partager sur Facebook
              • Partager sur Twitter
                22 mai 2021 à 14:52:21

                Remarques très pertinentes (je suis quand même assez septique sur "Connexion/épuisements des ports:").

                Quel est ce forum ?

                Pourquoi utiliser un constructeur statique "explicite" pour l'initialisation de certain champs statiques et pas d'autres (affectation à la déclaration) ?

                N'y-a-t-il pas toujours une limitation sur les applications Multi-AppDomain qui appellent plusieurs fois le constructeur statique (explicite et implicite) ?

                Merci.

                -
                Edité par bacelar 24 mai 2021 à 0:29:32

                • Partager sur Facebook
                • Partager sur Twitter
                Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                  23 mai 2021 à 23:35:00

                  Au départ, la classe que j'ai écrite dans la réponse avait plus de fonctionnalités Je les ai supprimés à la dernière minute en laissant le constructeur statique (le but était un Singleton pattern).Il n'y a donc aucune raison particulière maintenant qu'une construction statique est nécessaire. Désolé pour la confusion.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    24 mai 2021 à 0:31:53

                    Attention aux limitations d'un Singleton utilisant un constructeur statique.
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

                    Fichier images long à charger

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown