Laden...

Paralleler always running Code am besten implementieren vom WPF Projekt.

Erstellt von Sebrahi vor 3 Jahren Letzter Beitrag vor 3 Jahren 336 Views
S
Sebrahi Themenstarter:in
22 Beiträge seit 2020
vor 3 Jahren
Paralleler always running Code am besten implementieren vom WPF Projekt.

Hallo, ich habe ein WPF Projekt. In der WPF GUI wird das Programm StartWebcrawlingParallel aufgerufen.
Diese soll mehere headless Chromefenster starten in Parallel, die nie beendet werden sollen.
Diese Chromefenster greifen auch auf eine SQL-Server Datenbank zu.

Die Fragen die ich mir stelle sind:

  • sollte ich 1) Invoke 2) Task oder 3) Thread dafür benutzen?
  • wie viele ich davon erstellen soll für die beste Leistung. Ich besitze einen 16 kerne Processor, sollte ich dann 16 Task/Threads/Invoke erstellen?
  • Ist es ok ein WPF Projekt zu benutzen für AlwaysRunning Code? Ich möchte das mein Code die ganze Zeit läuft.

         public static void WebcrawlingAlwaysRunning()
        {
            
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.AddArguments("--headless");

            var driverService = ChromeDriverService.CreateDefaultService();
            IWebDriver driver = new ChromeDriver(driverService, chromeOptions);    
        
            while (true)
            {
                //web crawling 
            }

        }
        public static void StartWebcrawlingParallel_1()
        {
            Parallel.Invoke(WebcrawlingAlwaysRunning, WebcrawlingAlwaysRunning, WebcrawlingAlwaysRunning, WebcrawlingAlwaysRunning);            
        }
        public static void StartWebcrawlingParallel_2()
        {      
            Task Task = Task.Factory.StartNew(WebcrawlingAlwaysRunning);
            Task Task2 = Task.Factory.StartNew(WebcrawlingAlwaysRunning);
            Task Task3 = Task.Factory.StartNew(WebcrawlingAlwaysRunning);            
        }
        public static void StartWebcrawlingParallel_3()
        {
            Thread thread1 = new Thread(WebcrawlingAlwaysRunning);
            Thread thread2 = new Thread(WebcrawlingAlwaysRunning);
            Thread thread3 = new Thread(WebcrawlingAlwaysRunning);
            thread1.Start();
            thread2.Start();
            thread3.Start();
        }

P
441 Beiträge seit 2014
vor 3 Jahren

Prinzipiell ist der Lebenszyklus einer Desktop Applikation erst einmal an die Darstellung eines Fensters gebunden.
Was du beschreibst klingt eher nach einem Dienst als einer Desktop Applikation.

Wie viel Worker du machen solltest hängt nachher davon ab, wie viel die einzelnen Crawler machen (Bei Crawling wichtig: Die Webseiten-Eigentümer müssen genau dieses erlauben, was idr. nicht erlaubt ist) und wie nutzbar der PC noch sein soll.

Mit den Chrome selber habe ich leider keine Erfahrung, es klingt aber eher, als hättest du eine Reihe von Aufgaben, die abzuarbeiten und ggf. nicht endlich sind.
In dem Fall würde ich vermutlich eher auf ein Consumer/Producer Pattern gehen und aus einem IHostedService heraus neue Tasks starten.

T
2.224 Beiträge seit 2008
vor 3 Jahren

Was genau willst du mit dem Crawler machen?
Wenn du nur Ausgaben benötigst, kannst du den Crawler als eigene Anwendung umsetzen und mir Parametern entsprechende Seiten verarbeiten lassen.
Dann kannst du die Ausgabe über Console.Write* rausschreiben und in deiner Anwendung einlesen.

Generell machen solche Prozesse in Desktop Anwendungen aber nicht viel Sinn.
Kannst du ggf. noch ein paar Infos geben, was du damit vorhast.
Vielleicht gibt es einen sinnvolleren Weg.
Warum du hier via Chrome auf einen SQL Server zugreifst, ist mir nicht ganz klar.
Kannst du genauer erklären, was du damit meinst?
Klingt ohne Hintergrundwissen erstmal sehr nebulös und nicht umbedingt sinnvoll.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

2.079 Beiträge seit 2012
vor 3 Jahren

Frage 1:
Ich nutze Threads nur dann, wenn ich viel Kontrolle brauche, aber möglichst nur dann, wenn es um Code geht, der wirklich lange unabhängig vom Rest laufen soll. Also ein komplett eigenständig im Hintergrund laufendes System, das dann aber auch klar und deutlich vom Rest abgekapselt ist.

Wenn Du sozusagen aus deiner UI heraus eine Aufgabe starten möchtest, die dann im Hintergrund läuft und die UI regelmäßig informiert, ist die mit Abstand einfachste Lösung der Task.
Vergiss dabei aber nicht, dass Du mit einem neuen Task (Run oder Factory) viele der Vereinfachungen nicht mehr nutzen kannst, um die Vorteile wirklich ausnutzen zu können, solltest Du also wissen, was Du tust, doch das gilt für alle drei Wege.
Wenn Du einen neuen Task haben willst, der lange läuft, dann vergiss nicht, den als LongRunning zu markieren, sonst blockierst Du einen ThreadPool-Thread.

Frage 2:
Wenn Du deine CPU maximal auslasten möchtest, ist vermutlich Parallel die beste Option, die teilt (wenn nicht anders eingestellt) genau auf die logischen Kerne auf, auch wenn es mehr Aufgaben sind, als Du Kerne hast.
Mit den Threads direkt kannst Du sogar genau definieren, auf welchem Kern der Thread laufen soll (ProcessorAffinity), aber ob das so sinnvoll ist - ich bezweifle es.
Mit den Tasks geht das vermutlich nicht - ich habe aber auch noch nie danach gesucht.
Du solltest dir lieber überlegen, was Du brauchst und ob Du wirklich deine CPU 100% auslasten musst/solltest, denn sowas wie eine Desktop-Anwendung bekommt dann auch Probleme 😉

Frage 3:
Wie schon mehrfach gesagt sind Desktop-Anwendungen keine optimale Umgebung dafür.
Für dauerhaft laufenden Code solltest Du einen Dienst implementieren, das Desktop-Programm kommuniziert dann über eine geeignete Schnittstelle mit diesem Dienst.
Wenn es aber gewollt ist, dass die Aufgaben nur so lange laufen, wie die Desktop-Anwendung, dann kannst Du bedenkenlos WPF verwenden.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.