2016-06-11 4 views
1

Erstens, wenn dies eine Frage ist, die bereits gestellt wurde, werden Sie nicht wütend und verlinken Sie mich einfach mit dem Original, bitte, ich konnte es nicht finden. Danke :)Andere Ergebnisse erhalten, wenn Sie hineingegangen sind (Threading)

Ok, also weiß ich nicht wirklich, wie ich das erklären soll. Wenn ich in meinen Code eintrete, der alle Pixel einer Bitmap bekommt und in ein Wörterbuch in der Reihenfolge legt. Wenn ich in den Code eintrete, läuft alles perfekt und schließt schnell ab. Allerdings, wenn ich keine Breakpoints in, x und y bei colour = bmpThread.GetPixel(x,y); gehen Sie außerhalb der Grenzen und gehen Sie zu 4 und ich habe keine Ahnung warum. Warum macht es das und wie höre ich es auf?

void PixelAnalyse(int x, int y, int currentPixel) 
    { 
     Bitmap bmpThread = bmp; 

     Color colour; 

     lock (bmpThread) 
     { 
      colour = bmpThread.GetPixel(x, y); 
      //pTemp = bmpThread.GetPixel(x, y); 
     } 
     //this.Invoke(new Action(() => dataGridView1.Rows.Clear())); 

     //Get the pixel colours 
     arrayOfColours[currentPixel] = colour; 

     //this.Invoke(new Action(() => dataGridView1.FirstDisplayedCell = dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[0]));W 
     //this.Invoke(new Action(() => progressBar1.Value++)); 
     CancellationTokenSource cts = new CancellationTokenSource(); 

     cts.Cancel(); 
    } 

    private void analyse1_Click(object sender, EventArgs e) 
    { 
     ThreadPool.SetMaxThreads(imageSize + 1, imageSize + 1); 

     for (int m = 0; m < imageSize; m++) 
     { 
      arrayOfColours.Add(m, Color.Black); 
     } 

     int y, x; 
     int currentPixel = 0; 
     for (x = 0; x < xSize; x++) 
     { 
      for (y = 0; y < ySize; y++) 
      { 
       ThreadPool.QueueUserWorkItem(new WaitCallback(o => PixelAnalyse(x, y, currentPixel))); 
       currentPixel++; 
      } 
     } 

     PrintToDataGraph(); 
    } 

Antwort

1

Weil Sie die Erfassung der Variablen, nicht der aktuelle Wert von ihnen; im Grunde tun Sie dies:

  • Warteschlange eine Operation, die die Variable zugreiftcurrentPixel, x und y (ot des aktuellen Wertes)
  • Ändern Sie den Wert dieser Variablen
  • Schleife

Dies bedeutet, dass , wenn jede Operation tatsächlich passiert, die Werte von currentPixel, x und y sind nicht was sie waren, als Sie die Arbeit geplant haben.

Sie diese vermeiden können, auf dem niedrigsten Umfang neue Variablen, indem er erklärt:

var a = x; 
var b = y; 
var c = currentPixel; 
ThreadPool.QueueUserWorkItem(new WaitCallback(o => PixelAnalyse(a, b, c))); 

Allerdings ist es unwahrscheinlich, dass die Schaffung , dass viele Workitems ist ein optimaler Ansatz; Normalerweise sollten Sie eine kleinere Anzahl von "klobigen" Arbeitselementen für den Thread-Pool erstellen.

+0

Ah danke, das hat perfekt funktioniert. Und für die dickeren Arbeiten meinst du weniger Threads als mehr Arbeit, damit ich keine Zeit mit der Erstellung von Threads verschwenden muss? –

+0

@JoeRoy gut, technisch mit dem Thread Pool bist du sowieso nicht wirklich verantwortlich für die Threads - wann und wie viel es zuzuteilen ist nicht deine Sache - aber ja, ich spreche über die Reduzierung von Gemeinkosten. –

Verwandte Themen