Multithreading in C#, Teil 21: Erstellen und Starten eines Tasks

Ein Task kann immer dann zum Einsatz kommen wenn Codeabschnitte parallel ausgeführt werden sollen. Dabei spielt es keine Rolle ob es sich bei den Codeabschnitten um eine Zeile Code, mehrere Zeilen Code oder um komplexe Funktionen handelt. Wenn Sie solche Parallelisierungsaufgaben implementieren wollen, können Sie Tasks einsetzen. Diese verwalten intern alle benötigten Multithreadingobjekte und Sie müssen sich daher nicht selbst um das Erstellen, Stoppen und Freigeben von Threads kümmern. In diesem Artikel möchte ich Ihnen daher zeigen wie einfach es ist Tasks zu erstellen und auszuführen.

 
Task mit einem Codeabschnitt

Ein Task, der einen Codeabschnitt ausführen soll, kann mittels Task.Factory.StartNew erstellt und direkt gestartet werden. Der nachfolgende Quellcode zeigt eine entsprechende Konsolenanwendung.

class Program
{
    static void Main(string[] args)
    {
        Task.Factory.StartNew(() => Console.WriteLine("Hello World"));

        Console.ReadKey();
    }
}

 
Sie können einen Task selbstverständlich auch erst definieren und zu einem späteren Zeitpunkt starten. Dazu erzeugen Sie eine neue Task Instanz und starten diese zu einem beliebigen Zeitpunkt mittels der Start Funktion.

class Program
{
    static void Main(string[] args)
    {
        Task task = new Task (() => Console.Write ("Hello World"));

        task.Start();

        Console.ReadKey();
    }
}

 
Task mit einer Funktion

Genauso einfach wie ein Task zur Ausführung eines Codeabschnitts erzeugen werden kann, lässt sich auch eine Funktion in einem Task aufrufen. Der nachfolgende Quellcode zeigt die entsprechend angepasste Konsolenanwendung. Es werden zwei Tasks gestartet. Einer mit dem Aufruf eines Codeabschnittes und ein weiterer mit dem Funktionsaufruf.

class Program
{
    static void Main(string[] args)
    {
        Task.Factory.StartNew(() => Console.WriteLine("Hello Task 1"));
        Task.Factory.StartNew(DoWork);

        Console.ReadKey();
    }

    static void DoWork()
    {
        Console.WriteLine("Hello Task 2");
    }
}

 
Task mit einer Funktion und Rückgabewert

Eine Funktion welche Sie als Task ausführen kann einen Rückgabewert haben. Diesen können Sie sehr einfach mittels der Task Instanz auswerten. Diese stellt ein entsprechendes Result Property bereit.

class Program
{
    static void Main(string[] args)
    {
        Task<string> task = Task.Factory.StartNew<string>(DoWork);

        Console.WriteLine(task.Result);

        Console.ReadKey();
    }

    static string DoWork()
    {
        Console.WriteLine("Hello World");
        return "result of task";
    }
}

 
Nested Tasks

Innerhalb einer Task Funktion können Sie selbstverständlich weitere Tasks erzeugen und starten. Diese verhalten sich dabei standardmässig nicht anders als Tasks die auf gleicher Ebene erzeugt wurden. Durch ein entsprechendes Start Attribut können Sie aber eine Parent-Child Beziehung zwischen dem übergeordneten und den Nested Task herstellen. Diese Parent-Child Beziehung kommt dann zum Tragen wenn Sie auf den Abschluss eines Tasks warten. Hat dieser untergeordnete Child Tasks, so wird automatisch gewartet bis auch diese beendet wurden. Der nachfolgende Quellcode zeigt einen Task in welchem einen Child Task gestartet wird.

class Program
{
    static void Main(string[] args)
    {
        Task.Factory.StartNew(DoWork);

        Console.ReadKey();
    }

    static void DoWork()
    {
        Console.WriteLine("Main Task");

        Task.Factory.StartNew(
            () => Console.WriteLine("Child Task"),
            TaskCreationOptions.AttachedToParent);
    }
}

 
Task Creation Options

Im vorhergehenden Beispiel haben Sie bereits eine TaskCreationOption gesehen. Diese hat einen Task als Child eines anderen Tasks definiert. Die nachfolgende Tabelle zeigt alle TaskCreationOptions und deren Wirkung.

TaskCreationOption Wirkung
AttachedToParent Erzeugt einen Child Task
LongRunning Sollte für lang laufende und blockierende Tasks   verwendet werden. Der Scheduler plant diese lang laufenden Tasks so ein, dass   sie möglichst keine anderen Tasks am Starten hindern.
PreferFairness Der Scheduler wird versuchen die Tasks in der   Reihenfolge auszuführen in der diese erzeugt wurden.

 

Fazit
Codeabschnitte oder Funktionen parallel ausführen zu lassen ist mittels der Task Klasse zu einer trivialen Angelegenheit geworden. Sie müssen sich weder um das Erzeugen nach das Verwalten von Threads kümmern. Des Weiteren werden Tasks durch einen automatischen Scheduler effizient verwaltet.

Advertisements
Dieser Beitrag wurde unter .NET, C#, Multithreading abgelegt und mit , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Eine Antwort zu Multithreading in C#, Teil 21: Erstellen und Starten eines Tasks

  1. Pingback: Multithreading in C#, Teil 22: Beenden von Tasks | coders corner

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s