2009-10-20 7 views
0

Exemple1 public partial class Form1 : Form {appelant simultanément Graphics.Draw ou de nouveaux Bitmap de la mémoire en fil prendre beaucoup de temps

public Form1() 
    { 

     InitializeComponent(); 
    pro = new Thread(new ThreadStart(Producer)); 
    con = new Thread(new ThreadStart(Consumer)); 
    } 
    private AutoResetEvent m_DataAvailableEvent = new AutoResetEvent(false); 
    Queue<Bitmap> queue = new Queue<Bitmap>(); 
    Thread pro; 
    Thread con ; 

    public void Producer() 
    { 
     MemoryStream[] ms = new MemoryStream[3]; 
     for (int y = 0; y < 3; y++) 
     { 
      StreamReader reader = new StreamReader("image"+(y+1)+".JPG"); 
      BinaryReader breader = new BinaryReader(reader.BaseStream); 

      byte[] buffer=new byte[reader.BaseStream.Length]; 
      breader.Read(buffer,0,buffer.Length); 
      ms[y] = new MemoryStream(buffer); 
     } 
     while (true) 
     { 
      for (int x = 0; x < 3; x++) 
      { 
       Bitmap bmp = new Bitmap(ms[x]); 
       queue.Enqueue(bmp); 

       m_DataAvailableEvent.Set(); 
       Thread.Sleep(6); 
      } 
     } 
    } 
    public void Consumer() 
    { 
     Graphics g= pictureBox1.CreateGraphics(); 
     while (true) 
     { 
      m_DataAvailableEvent.WaitOne(); 
      Bitmap bmp = queue.Dequeue(); 
      if (bmp != null) 
      { 
       // Bitmap bmp = new Bitmap(ms); 
       g.DrawImage(bmp,new Point(0,0)); 
       bmp.Dispose(); 

      } 
     } 

    } 
    private void pictureBox1_Click(object sender, EventArgs e) 
    { 

     con.Start(); 
     pro.Start(); 

    } 
} 

lors de la création bitmap et le dessin à l'image boîte sont en fil individuelle puis Bitmap bmp = new Bitmap (ms [x]) prennent 45,591 millisecondes et g.DrawImage (BMP, nouveau point (0,0)) prendre 41,430 milisecond

quand je fais bitmap de MemoryStream et dessiner à l'image dans une boîte de fil puis bitmap bmp = new bitmap (ms [x]) prendre 29.619 et g.DrawImage (bmp, nouveau point (0,0)) prendre 35.540 le code est pour l'exemple 2 est

pourquoi il prend plus de temps pour dessiner et bitmap prendre le temps dans un fil séparé et comment réduire le temps lors du traitement dans thread séparé. J'utilise le profileur de performance ANTS 4.3 public Form1() {

 InitializeComponent(); 
    pro = new Thread(new ThreadStart(Producer)); 
    con = new Thread(new ThreadStart(Consumer)); 
    } 
    private AutoResetEvent m_DataAvailableEvent = new AutoResetEvent(false); 
    Queue<MemoryStream> queue = new Queue<MemoryStream>(); 
    Thread pro; 
    Thread con ; 

    public void Producer() 
    { 
     MemoryStream[] ms = new MemoryStream[3]; 
     for (int y = 0; y < 3; y++) 
     { 
      StreamReader reader = new StreamReader("image"+(y+1)+".JPG"); 
      BinaryReader breader = new BinaryReader(reader.BaseStream); 

      byte[] buffer=new byte[reader.BaseStream.Length]; 
      breader.Read(buffer,0,buffer.Length); 
      ms[y] = new MemoryStream(buffer); 
     } 
     while (true) 
     { 
      for (int x = 0; x < 3; x++) 
      { 
       // Bitmap bmp = new Bitmap(ms[x]); 
       queue.Enqueue(ms[x]); 

       m_DataAvailableEvent.Set(); 
       Thread.Sleep(6); 
      } 
     } 
    } 
    public void Consumer() 
    { 
     Graphics g= pictureBox1.CreateGraphics(); 
     while (true) 
     { 
      m_DataAvailableEvent.WaitOne(); 
      //Bitmap bmp = queue.Dequeue(); 
      MemoryStream ms= queue.Dequeue(); 
      if (ms != null) 
      { 
       Bitmap bmp = new Bitmap(ms); 
       g.DrawImage(bmp,new Point(0,0)); 
       bmp.Dispose(); 

      } 
     } 

    } 
    private void pictureBox1_Click(object sender, EventArgs e) 
    { 

     con.Start(); 
     pro.Start(); 

    } 

+0

À mon humble avis, 3 images ne suffisent pas à porter un jugement sur la performance. La différence dans les temps d'exécution peut être causée par plusieurs facteurs. Je vous recommande de faire plus de mesures. HORS SUJET: Le code que vous avez écrit ici n'est pas bien-parallélisé: (1) vous lisez TOUTES les images avant de le passer au consommateur - il est préférable de les charger et de les passer une par une; (2) votre implémentation de Prod/Cons est cassée ce qui peut être vu par l'apparition de Thread.Sleep call. Réécrivez-le en utilisant des sémaphores (voir ici http://en.wikipedia.org/wiki/Producer-consumer_problem). Vous devez également disposer l'objet Graphics que vous créez. –

Répondre

0

Toutes les opérations d'interface utilisateur doivent avoir lieu sur le même thread. En fait, si vous voulez que votre système soit stable, ils doivent tous avoir lieu sur le même fil. Je suppose que ce que vous voyez avec les performances plus lentes sur le code multithread est la preuve de cette instabilité.

De toute façon, chargez les images dans des threads séparés, mais mettez à jour l'interface utilisateur dans le thread principal.

Si vous recherchez des questions marquées [multithreading] [C#] ici sur Stack Overflow vous verrez beaucoup d'autres questions dans le même sens que la vôtre.

Voir par exemple here et here.

Questions connexes