Sollten .Net 4.0-Tasks immer die bevorzugte Methode für Multithread-Anwendungen sein?

  • Ich las über die Task Parallel Library und den Artikel Folgendes wurde gesagt:

    In .NET Framework 4 sind Tasks die bevorzugte API zum Schreiben von Multithread-Code, asynchronem und parallelem Code

    Es heißt aber auch, dass sie den ThreadPool im Hintergrund verwenden. Ich habe Schwierigkeiten, herauszufinden, ob Aufgaben nur verwendet werden sollten, wenn Sie einen ThreadPool verwenden würden ("Thread versus Task" wäre daher gleichbedeutend mit "Thread versus ThreadPool") oder ob Microsoft beabsichtigt, dass Aufgaben verwendet werden Es sind überall mehrere Threads erforderlich, ohne dass das Dilemma "Thread versus ThreadPool" in Betracht gezogen wird.

    Sollten Tasks überall dort verwendet werden, wo mehrere Threads erforderlich sind?

    22 November 2011
    Bob
3 answers
  • Der Entwurfsvorteil bei der Verwendung von Aufgaben besteht darin, dass Sie das Kernstück des Einfädelns zur Laufzeit übergeben, was vermutlich die Einfädelungsaufgaben mit einer weniger fehlerhaften, optimaleren Lösung erledigen könnte. Ich kenne bestimmte aufgabenbasierte Paradigmen wie PLINQ, mit denen Sie Hinweise geben können, welche Strategie die Laufzeit übernehmen sollte, sodass die Frage "Threadpool oder nicht Threadpool" direkt behandelt werden kann.

    Die Umstellung auf dieses Modell ist analog zur Umstellung auf eine verwaltete GC-ed-Sprache gegenüber einer Sprache, für die Sie Ihren eigenen Speicher aufräumen müssen. Es wird immer Argumente für Letzteres geben, aber die Garbage Collection wird jetzt so optimiert, dass es praktisch kein Thema ist. Idealerweise wird der Laufzeitumschaltmechanismus für Tasks weiterentwickelt und verbessert. Theoretisch könnte Ihre für .NET 4 geschriebene und kompilierte Anwendung mit besseren Implementierungen der Laufzeit ohne weitere Neukompilierung schneller werden. Das Einfädeln von Code ist bekanntermaßen schwer zu finden, daher ist jeder Mechanismus, der diese Details verbirgt, für den Programmierer gut.

    Ob diese Vorteile potenzielle Nachteile überwiegen, z. B. Randfälle, mit denen die Laufzeit nicht gut zurechtkommt, sollten von Fall zu Fall betrachtet werden. Ich würde sicherlich versuchen, hier nicht frühzeitig zu optimieren.

    22 November 2011
    cunningdave
  • Sie können TaskCreationOptions.LongRunning als Hinweis verwenden, um der TPL mitzuteilen, dass Ihre Aufgabe möglicherweise mehr als die Aufgabe von ThreadPool umfasst. Ja, die TPL scheint die bevorzugte Methode für die Multithread-Programmierung zu sein. Microsoft baut sogar darauf auf, um die neuen Schlüsselwörter async und await zu unterstützen, die in den Async CTP . Das bedeutet nicht, dass Sie die alten APIs Thread und ThreadPool vollständig aufgeben müssen. Ich persönlich finde jedoch, dass die TPL das meiste tut, was ich mit einer eleganteren API erreichen möchte, und ich verlasse mich jetzt fast ausschließlich darauf.

    22 November 2011
    Brian Gideon
  • Eine Aufgabe ist eine Abstraktion auf höherer Ebene als ein Thread oder ein ThreadPool. Im Wesentlichen packen Sie eine Funktion in eine Task und bitten die Laufzeitumgebung, sie so gut wie möglich auszuführen. Sie können viele Dutzend, wenn nicht Hunderte von Tasks haben, die von einer begrenzten Anzahl von Threads ausgeführt werden.

    Mit Aufgaben erstellt ein Entwickler so viele Aufgaben wie erforderlich, kettet sie an, um Flüsse (Workflows in F #) zu erstellen und deren Abbruch zu steuern, ohne sich mit der Zuweisung oder Verwendung von Threads zu beschäftigen. Es liegt an der Laufzeit, die beste Methode auszuwählen, um alle Tasks mit einer begrenzten Anzahl von Threads auszuführen.

    Aufgaben erleichtern die Implementierung gleichzeitig ablaufender Programmiermuster. Die Bibliothek ParallelExtensionExtras enthält Methoden zum Konvertieren von Begin / EndXXX paart sich mit Tasks, die verkettet werden können, und einer vorläufigen Version des Task-Iterations-Idioms, das von Async CTP verwendet wird, um die Async / await-Syntax bereitzustellen. Sie können eine ConcurrentCollection von Aufgaben verwenden, um eine Warteschlange von Jobs zu erstellen, ähnlich dem AsyncCall-Beispiel in ParallelExtensionExtras, oder gehen Sie noch weiter und erstellen Sie Agenten, die Scala, Erlang oder F # ähneln. Der Datenfluss im Async-CTP ist ein weiteres Beispiel dafür, was Sie mit Aufgaben erstellen können.

    Sie müssen bedenken, dass ein typischer Laptop über 2 Kerne verfügt und ein typischer Desktop 4, haben kleine Server bereits 8 oder mehr Kerne und bald werden sie viele mehr haben. Wenn Sie diese Kernbereiche durch manuelles Planen von Threads und das Vermeiden von Blöcken auf Trab halten, kann dies zu erheblichen Kopfschmerzen führen.

    22 November 2011
    Panagiotis KanavosSonic Soul