2009-05-25 5 views
1

J'ai une application Windows Forms dans .NET 3.5. Il y a un formulaire avec 20 boîtes d'images. Il y a aussi un tableau avec 20 URL d'image. L'objectif est de parcourir le tableau des URL et de charger les images du Web dans les zones d'image.Comment puis-je utiliser des threads en C# pour charger plusieurs images à la fois sur le Web?

J'ai essayé d'avoir une boucle foreach standard et d'utiliser la méthode LoadAsync() de la zone d'image, mais cela ne fonctionne pas. Il chargera l'image pour les 6 premières cases d'image et échouera pour l'autre 14. Je crois que la raison a quelque chose à faire avec trop de demandes en même temps. Mais je ne suis pas sur. Donc je veux essayer un code manuel multithread, où j'utiliserais la méthode Load() synchrone de la boîte d'image, et autoriserais un maximum de 3 threads chargeant l'image du Web en même temps.

Une idée sur la façon de mettre en œuvre cela? Fondamentalement, j'ai besoin de savoir comment autoriser 3 threads en même temps, à partir d'une file d'attente à traiter.

Merci!

Répondre

8

BackgroundWorker est une bonne classe pour exécuter des tâches sur fond threads dans les applications winforms. Voici un petit échantillon que j'ai écrit pour vous démontrer son utilisation:

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 

     // Declare a list of URLs and their respective picture boxes 
     var items = new Dictionary<string, PictureBox> 
     { 
      { "http://www.google.com/logos/spring09.gif", new PictureBox() { Top = 0, Width = 300, Height = 80 } }, 
      { "http://www.google.com/logos/stpatricks_d4gwinner_eo09.gif", new PictureBox() { Top = 100, Width = 300, Height = 80 } }, 
      { "http://www.google.com/logos/schiaparelli09.gif", new PictureBox() { Top = 200, Width = 300, Height = 80 } }, 
      { "http://www.google.com/logos/drseuss09.gif", new PictureBox() { Top = 300, Width = 300, Height = 80 } }, 
      { "http://www.google.com/logos/valentines09.gif", new PictureBox() { Top = 400, Width = 300, Height = 80 } }, 
      { "http://www.google.com/logos/unix1234567890.gif", new PictureBox() { Top = 500, Width = 300, Height = 80 } }, 
      { "http://www.google.com/logos/charlesdarwin_09.gif", new PictureBox() { Top = 600, Width = 300, Height = 80 } }, 
     }; 

     foreach (var item in items) 
     { 
      var worker = new BackgroundWorker(); 
      worker.DoWork += (o, e) => 
      { 
       // This function will be run on a background thread 
       // spawned from the thread pool. 
       using (var client = new WebClient()) 
       { 
        var pair = (KeyValuePair<string, PictureBox>)e.Argument; 
        e.Result = new KeyValuePair<PictureBox, byte[]>(pair.Value, client.DownloadData(pair.Key)); 
       } 
      }; 
      worker.RunWorkerCompleted += (o, e) => 
      { 
       // This function will be run on the main GUI thread 
       var pair = (KeyValuePair<PictureBox, byte[]>)e.Result; 
       using (var stream = new MemoryStream(pair.Value)) 
       { 
        pair.Key.Image = new Bitmap(stream); 
       } 
       Controls.Add(pair.Key); 
      }; 
      worker.RunWorkerAsync(item); 
     } 
    } 
} 
1

Je voudrais jeter un coup d'oeil à la collection Synchronized Queue disponible à partir de System.Collections, si vous cherchez à utiliser une file d'attente avec plusieurs threads.

En outre, le lien suivant est une excellente introduction aux threads en C#. Covers quels fils sont, quand les utiliser (et quand ne pas), la façon de démarrer et de fils arrêter et comment faire vos opérations de base thread-safe et beaucoup plus: Threading in C#

+0

Merci, c'est une belle page. Je viens de lire à propos du sémaphore et je vais essayer de l'utiliser pour réaliser ce dont j'ai besoin. – LeoD

Questions connexes