Ich hab kürzlich die BASTA Spring 2010 besucht (über 500 Teilnehmer). Es war wirklich eine sehr informative Veranstaltung über aktuelle Entwicklungen im .NET Bereich. Folgender Abriss soll die Neuerungen im .NET Framework 4.0, Entity Framework 2, VisualStudio 2010, WPF 4 und Silverlight 4, aufzeigen.
Im folgenden Artikel möchte ich über das Neue in der parallelen Programmierung mit dem .NET 4.0 Framework schreiben:
Parallel Programming – PLINQ, Task, Concurrency
In der Vergangenheit konnten Anwendungen automatisch von neueren Prozessoren mit höheren Taktfrequenzen profitieren (Jedes Jahr Verdopplung der Taktfrequenz). Diese Gesetzmäßigkeit wird sich in der Zukunft nicht mehr fortsetzen (Wärmeentwicklung etc…). Die Leistungsfähigkeit moderner Prozessoren steigert sich heute in der Regel durch den gleichzeitigen Einsatz mehrerer CPU-Kerne. Da Anwendungsentwickler nicht mehr darauf bauen können, dass eine sequentiell implementierte Anwendung auf einer neueren CPU-Generation schneller ausgeführt wird, müssen die Möglichkeiten der Multicore-Technologie gezielt genutzt werden. Der Schlüssel dazu lautet “Parallel Computing”.
Man unterscheidet hier zwischen lineares Aufteilen von Aufgaben und Daten, sowie zwischen hierarchisches Aufteilen von Aufgaben und Daten.
Task
Der Task Parallel Library (TPL) ist ein Satz von öffentlichen Typen und APIs im System.Threading und System.Threading.Tasks Namespaces in .NET Framework 4.0. Diese Typen verlassen sich auf einen Taskplaner, die in der .NET ThreadPool integriert ist. Die TPL hilft den Entwicklern, Produktivität zu steigern und die Parallelität in den Anwendungen vereinfacht.
Entwickler teilt Algorithmus auf Tasks auf.
- TPL teilt diese Tasks den einzelnen CPUs (Kernen) zu.
- Auslastung vorhandener Ressourcen und Skalierbarkeit
Beispiel Task erzeugen
1 2 3 4 | using System.Threading.Tasks; void DoStuff() { Console.WriteLine("Hello!"); } Task t = Task.Factory.StartNew(DoStuff); t.Wait(); |
Lambda Alternative
1 2 3 | using System.Threading.Tasks; Task t = Task.Factory.StartNew(() => Console.WriteLine("Hello!");); t.Wait(); |
Task und parallele Schleifen
Beispiele:
1 2 | Parallel.ForEach(List<Persons>, (p) => Console.WriteLine(p.Name)); Parallel.For(0, 10, (i) => Console.WriteLine(i.ToString())); |
Task mit Rückgabewerte
Beispiele:
1 2 3 | Task t = ... Task.Factory.StartNew<Person>( () => ...); Person p = t.Result; |
Task-Ketten
Beispiele:
1 2 | Task<Person> task = Task.Factory.StartNew<Person>(() => DoWithPerson()); Task task2 = task.ContinueWith((t) => AndNowDoAnyWithPerson(t.Result)); |
Auf Task warten
Beispiele:
1 2 3 4 5 | t.Wait(); Task[] tasks = ... Task.WaitAll(tasks, (finishedTasks) => ...); Task[] tasks = ... Task.WaitAny(tasks, (finishedTasks) => ...); |
Task abbrechen
Beispiele:
1 2 3 4 5 6 7 8 9 10 | var source = new CancellationTokenSource(); CancellationToken token = source.Token; Task t = Task.Factory.StartNew(() => { while (true) { if (token.IsCancellationRequested) { throw new OperationCanceledException(token); } } }); source.Cancel(); |
Task Exceptionhandling
Beispiele:
1 2 3 4 5 6 7 8 9 10 11 | try { Task t = Task.Factory.StartNew(...); source.Cancel(); t.Wait(); } catch (AggregateException ae) { ae.Handle( (e) => { Console.WriteLine(e.Message); return true; }); } |
PLINQ
Parallel LINQ (PLINQ) ist eine parallele Implementierung vom LINQ-Muster. PLINQ-Abfrage in vielerlei Hinsicht ähnelt eine nicht parallelen LINQ to Objects-Abfrage.PLINQ-Abfragen, wie sequenzielle LINQ Abfragen beziehen sich auf alle im Arbeitsspeicher IEnumerable oder IEnumerable
Beispiel:
1 2 3 4 5 6 7 8 9 10 11 12 | var q = from p in menu.AsParallel() where p.Price >= 4 select p.Name; var q = from p in menu .AsParallel() .AsOrdered() .WithCancellation(token) .WithDegreeOfParallelism(3) .WithExecutionMode(…) .WithMergeOptions(…) where p.Price >= 4 select p.Name; |
Partitionierung in PLINQ
Beipiel:
(from x in D.AsParallel() where p(x) select x*x*x).Sum();
Quellen:
Webcasts:
- Einführung [4]
- Tasks verketten [5]
- Exception handling [6]
- Empfehlenswerte 6teilige Serie von Bernd Marquardt (Parallelprogrammierung mit der Task Parallel Library) [7]
Weitere Downloads:
- Understanding and Applying Parallel Patterns with the .NET Framework 4 [pdf] download
Concurrency
Concurrency Runtime (C++)
Der Concurrency Runtime Scheduler ist ein “stehlender” Algorithmus zum Verteilen der Arbeit unter den Computerressourcen. Tasks werden auf die Worker Threads verteilt und parallel ausgeführt. Sobald einer der Worker Threads nichts zu tun hat, “stiehlt” er eine laufende Aufgabe eines anderen Worker Threads, was zu einer besseren Auslastung der vorhandenen Prozessorkerne führt.
Architektur
Die Concurrency Runtime ist in vier Komponenten eingeteilt
- Parallel Patterns Library (PPL)
- Asynchronous Agents Library
- Task Scheduler
- Resource Manager
Die Komponenten befinden sich zwischen dem Betriebssystem und der Anwendung. Die folgende Abbildung zeigt, wie die Laufzeitkomponenten zwischen OS und Applikation interagieren:
Quellen:
Im nächsten Artikel schreibe ich über weitere Neuerungen und Veränderungen im .NET Framework 4.0










