Laden...

Methode mehrfach parallel ausführen/ Unterschied Thread und Task

Erstellt von Gimmick vor 6 Jahren Letzter Beitrag vor 6 Jahren 3.259 Views
G
Gimmick Themenstarter:in
154 Beiträge seit 2015
vor 6 Jahren
Methode mehrfach parallel ausführen/ Unterschied Thread und Task

Hallo,

ich habe ein Programm geschrieben, dass so funktioniert:
*siehe Anhang*

Ausgangssituation: 4 Bilddateien wurden ausgewählt, d.h. ihr Pfade wurden geladen.

Durch Knopfdruck wird eine Datei Byte-weise gelesen und in eine Array gespeichert. Damit werden dann durch die Methoden verschiedene Dinge berechnet. Die Methoden sind verschachtelt, rufen sich also der Reihe nach auf und geben jeweils wieder einen Wert eine Eben nach unten zurück.

Das Ergebnis beinhaltet nach für jedes Bild eine Ausgabe in eine Textbox und das Zeichnen von Makierungen in das Bild.

Eine vollständige Dateiauswertung kann schon mal eine Weile dauern. (Die Einteilung von Pixeln in Cluster, Rauschen usw. dauert).

Daher würde ich das gerne für alle 4 Dateien parallel machen.
Das ist das erste mal, dass ich mich mit Threads/Tasks beschäftige. Mir ist aber der Unterschied zwischen Tasks und Threads nicht klar.

Also sowas wie :


string[] Pfade = [Pfad1,Pfad2,Pfad3,Pfad4];

Tue gleichzeitig
{
List<Point> Ergebnis1 = Methode1(Pfad1);
List<Point> Ergebnis2 = Methode1(Pfad2);
List<Point> Ergebnis3 = Methode1(Pfad3);
List<Point> Ergebnis4 = Methode1(Pfad4);
}

👅 😁

Ich hab mal ein wenig mit Threads rumgespielt, aber da hat bisher die Rückgabe nicht funktioniert und entgegen miner Erwartung wurden die Ergebnisse (einfache Addition) nicht, ich sag mal annähernd, abwechselnd ausgegeben, sondern nacheinander.
Vielleicht wäre es aber auch besser mit Tasks zu arbeiten?

Hätte jemand ein paar Tips dazu, wie ich das angehen sollte?

709 Beiträge seit 2008
vor 6 Jahren

Hallo,
hast du hier schon mal reingesehen: [Artikel] Multi-Threaded Programmierung ?

1.029 Beiträge seit 2010
vor 6 Jahren

Hi,

na wenn's nicht funktioniert wie du möchtest wäre ein Codebeispiel ja sinnvoll.

Unabhängig davon solltest du berücksichtigen:
a) Multithreading für Datei-Operationen lohnt sich selten
b) Von einem nicht UI-Thread auf die UI zuzugreifen wird so nicht funktionieren

LG

G
Gimmick Themenstarter:in
154 Beiträge seit 2015
vor 6 Jahren

Nach einem Tip eines Kollegen habe ich es über Parallel.ForEach gelöst.
Ich wusste nicht, dass es das gibt ^^.

6.911 Beiträge seit 2009
vor 6 Jahren

Hallo Gimmick,

Mir ist aber der Unterschied zwischen Tasks und Threads nicht klar.

Thread (Informatik) sagt da so ziemlich viel.

Ein Task (eingeführt mit .net 4.0) ist eine "Aufgabe" die dem Task-Scheduler übergeben wird. Dieser kümmert sich dann darum, dass der Task ausgeführt wird. Die Ausführung kann -- muss aber nicht, obwohl i.d.R. wird es so sein -- in einem Thread (genauer ThreadPool-Thread) erfolgen.

D.h. ein Task ist grob eine Abstraktion von Threads und das Arbeiten (hier programmieren) mit Tasks ist einfacher als mit Threads.

Bzgl. deiner Aufgabenstellung könnte auch Pipelines interessant sein. Wobei ich dir gleich auch empfehle das ganze eBook durchzugehen, dann hast du einen guten Einstieg in Tasks 😃

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

G
Gimmick Themenstarter:in
154 Beiträge seit 2015
vor 6 Jahren

Hi,

den Link über Pipelines werde ich mir mal ansehen.

Aber mal auf die schnelle:

Ich habe folgendes gemacht:


private void button1_Click(object sender, EventArgs e)
        {

            Parallel.ForEach(Pfade, element =>
           {
               
               DoStuff(element);

           });

        }



private void DoStuff(string path)
        {
            IEImage Bild = new IEImage(path);
            string name;
            name = Path.GetFileName(path);
            
            Organizer(Bild);
                 
                        
        }


private void Organizer(IEImage Bild)
        {
            Bild.ConvertToGray();
            Bild.EdgeDetect_Sobel();
            
            //Vorverarbietetes Bitmap
            Bitmap VorverarbeitetBitmap = Bild.CreateBitmap();
            
            //Array für Cluster
            List<Point> points = BildArray(VorverarbeitetBitmap);
            
            //Randbestimmung
            List<Point> Rand = DBRAND(points);
            
            //Feststellung der Neigung
            bool neigung = Neigung(Rand);
           
            //Sortieren
            List<Point> sortierung = Sortierung(Rand);

            //Bestimmung des Eckpunktes
             Point ecke = Ecke(sortierung,neigung);

            //Berechnung der Gerade mit den meisten Treffern
            List<Point> Bresenergebnis = Geraden(ecke, neigung, sortierung);

            //Messung Distanz Ecke <-> Kurve in Pixeln
            double distanz = Distanz(Bresenergebnis, ecke, neigung);

            //more Stuff inc

        }


Wenn ich jetzt 4 Bilder einlese geht das manchmal schnell und manchmal breche ich nach 2 min ab, weil scheinbar garnichts passiert (aber es wird gerechnet laut Visual Studio Anzeige).

Bis auf Rückgabewerte in "Organizer" zurück habe ich keinerlei Ausgaben in den Methoden.

Woran kann das denn liegen, bzw nach was könnte ich da schauen?

6.911 Beiträge seit 2009
vor 6 Jahren

Hallo Gimmick,

bzw nach was könnte ich da schauen?

Hierher :rtfm: Sonst ist das so auf die Schnelle nicht zielführend. Schau dir lieber gleich an wie es "richtig" geht und bau keine Hack-Lösung die von Problem zu Problem surft.

Das ist Code-Snippet beachtet außerdem [FAQ] Warum blockiert mein GUI? nicht.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

G
Gimmick Themenstarter:in
154 Beiträge seit 2015
vor 6 Jahren

Das ist Code-Snippet beachtet außerdem
>
nicht.

Hab ich geändert =)

Es schent jetzt auch nicht mehr manchmal endlos zu rechnen, das Problem scheint Bild.ConvertToGray(); und Sobel gewesen zu sein.
Das sind Funktionen aus einer Bibliothek und scheinbar mag das keine parallele Ausführung. Habe den Teil ins Serielle umgeschrieben und jetzt klappts (bisher ^^).

6.911 Beiträge seit 2009
vor 6 Jahren

Hallo Gimmick,

wo hast du das geändert? Oben schaut es gleich aus.

einer Bibliothek und scheinbar mag das keine parallele Ausführung

Da sollte auch in der Doku der Bibliothek stehen. Du kannst aber dennoch "parallel" arbeiten, wenn du die oben erwähnten Pipelines verwendest, denn dort wird (bzw. kann) jeder Schritt nur einmal gleichzeitig ausgeführt werden, dafür aber mehrere Schritte wie Laden, Sobel, etc. zur gleichen Zeit.

Parallel.ForEach ist oft die scheinbar einfachste Möglichkeit der Beschleunigung des Programmablaufs, meist ist es aber nicht die passendste und es gibt bessere Alternativen.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"