Multitasking ist schon lange nicht mehr einfach nur ein schönes Wort. Multitasking wird vor allem in der zeit von mehr Kern Prozessoren immer wichtiger. Mit Hilfe der "Parallel" Klasse lassen sich in C# ganz einfach Schleifen erstellen die mit mehreren Tasks arbeiten und für den Programmierer keinen mehr Aufwand mit bringen.

Ein beispiel und eine Demonstration zeige ich euch in diesem Beitrag.

Vergleich For & Parallel.For

Die erste Frage die geklärt werden sollte ist "Warum sollte ich die Parallel.For Funktion überhaupt verwenden ?". Um diese frage zu beantworten hohle ich mir Hilfe bei der Stopwatch Klasse, mit dieser lassen sich Zeitabstände auf den Tick genau messen.

Verglichen werden die Ausführungszeiten einfacher Schleifendurchläufe:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;

namespace Parallel_Sample
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch sw=new Stopwatch();

            sw.Start();
            for (var i=0; i < 100000000; i++) ;
            sw.Stop();
            Console.WriteLine("Dauer Sequentiel: {0}", sw.ElapsedMilliseconds);

            sw.Reset();

            sw.Start();
            Parallel.For(0, 100000000, i => {} );
            sw.Stop();
            Console.WriteLine("Dauer Synchron: {0}", sw.ElapsedMilliseconds);
        }
    }
}

Dies erzeugt folgende Ausgabe:
Code:
Dauer Sequentiell: 235
Dauer Synchron: 158
Dies Zeigt uns das das Parallel.For ganze 77 Millisekunden schneller war als die normale For schleife.

Dies scheint auf den ersten Blick noch nicht viel, sobald wir aber die Schleifendurchläufe erhöhen wird der Vorteil der Parallel.For immer deutlicher, alternativ wird es auch deutlich wenn ein Thread.Sleep(1) in den Schleifen Body hinzugefügt wird. (Dabei empfehle ich allerdings die Schleifendurchläufe auf 1000 oder 10.000 zu senken. Nach der Modifizierung
Code:
for (var i=0; i < 1000; i++)
{
    Thread.Sleep(1);
}
Code:
Parallel.For(0, 1000, i => {
    Thread.Sleep(1);
} );

Nun ist der Unterschied deutlicher zu sehen, denn der Output ist wie folgt:
Code:
Dauer Sequentiell: 1934
Dauer Synchron: 252
Nun haben wir bei nur 1.000 Durchläufen schon 1682 Millisekunden gespart.

Vorteile / Nachteile

Zu den größten vorteilen zählt natürlich der große Geschwindigkeitsvorteil, hier ist allerdings zu beachten das dies nur bei Merkern Prozessoren der Fall ist, bei einer Single Core Umgebung erhält man keinerlei Geschwindigkeitsvorteil durch ein Parallel.For. Allerdings verdeutlicht sich der Geschwindigkeitsvorteil im Verhältnis zu der benötigten Ausführungszeit des Schleifen Körpers. Mit mehr Prozessor Nutzung steigt natürlich auch die Prozessorlast. Dazu kommt das durch die Verwendung von Threads muss der Schleifen Körper Thread Safe programmiert werden.

Desweiteren ist die Parallel.For Schleife für aufgaben die hintereinander erledigt werden müssen natürlich vollkommen unnütz, diese müssen weiterhin Sequentiell abgearbeitet werden.



Das Exception Handling sowie die Parallel.ForEach schleife werde ich in einem Späteren beitrag noch behandeln (werde den Link dann auch hier rein editieren)