2009-05-25 3 views
1

私は.NET 3.5でWindowsフォームアプリケーションを持っています。 1つのフォームに20個の画像ボックスがあります。 20個の画像URLを持つ配列もあります。目標は、URLの配列をループし、画像をWebから画像ボックスに読み込むことです。C#のスレッドを使って、一度に複数の画像をWebから読み込むことはできますか?

標準のforeachループを使用して、画像ボックスのLoadAsync()メソッドを使用しようとしましたが、動作しません。それは最初の6枚の画像ボックスの画像をロードし、他の画像ボックスでは失敗します。私は、その理由が同時に多くのリクエストに関係すると考えています。確信はないけど。

私は、画像ボックスの同期Load()メソッドを使用し、同時にWebから画像をロードする最大3つのスレッドを許可するマニュアルマルチスレッドコードを試したいと考えています。

これはどのように実装するのですか?基本的には、キューから同時に3つのスレッドを処理する方法を知る必要があります。

ありがとうございます!

答えて

8

BackgroundWorkerはバックグラウンドでタスクを実行するための良いクラスですWinFormsアプリケーションのスレッド。ここに、その使用法を示すために書いた小さなサンプルがあります:

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

複数のスレッドでキューを使用する場合は、System.Collectionsから入手可能なSynchronized Queueコレクションを参照してください。

また、次のリンクは、C#のスレッドの素晴らしい紹介です。起動と停止のスレッドをし、あなたの基本的な操作は、安全ではるかにスレッド作成する方法する方法を、彼ら(といないときに)を使用する場合は、スレッドが何であるかを説明しますThreading in C#

+0

ありがとう、それは素敵なページです。私はセマフォについて読んだだけで、必要なものを達成するためにそれを使用しようとします。 – LeoD

関連する問題