| 

.NET C# Java Javascript Exception

3
Hallo zusammen,
mal angenommen, ich habe hier mehrere parallele Tasks laufen. Ich nenne sie mal Jobs.
Nun kann es vorkommen, dass ein bestimmter Job erst ausgeführt werden soll/kann, wenn das Ergebnis aus einem anderen Job vorliegt.
Die Jobs werden zur Laufzeit definiert und so kann die Wartezeit zwischen ein paar Mikrosekunden und mehreren Sekunden liegen.

while(Results[jobTicket.Id] == null && !Timeout)
Thread.Sleep(1)

würde zwar funktionieren, erscheint mir aber - hmm... - naja, wenig elegant (um es mal höflich zu sagen).
17.01.2013
Cyron 86 5
4 Antworten
3
Den Wartevorgang über Timeout und Thread.Sleep abzubilden, ist nicht anzuraten. Dabei können zuviele Nebeneffekte auftreten.
Klassischerweise verwendet man Synchronisierungsprimitive. Hierzu zählen u.a. Mutex, Semaphore, Monitor, Events, ...
Seit Einführung der TPL wurden weitere Synchornisierungselemente hinzugefügt (z.B. Barrier, CountdownEvent, ...), die einem das Leben leichter machen.
Viele dieser Elemente bilden den Wartemechanismus mit Hilfe eines WaitHandle ab, sind also entweder davon abgeleitet (z.B. Mutex) oder stellen eine Property zur Verfügung, mit Hilfe derer man ein WaitHandle abrufen kann.

So etwas könnte für 2 Threads z.B. so aussehen:
static void Main(string[] args)
{
ManualResetEvent waitHandle = new ManualResetEvent(false);

Task.Factory.StartNew(() =>
{
Console.WriteLine("Perform long running operation");
Thread.Sleep(2000);
waitHandle.Set();
});

Console.WriteLine("start to wait");
waitHandle.WaitOne(); // ohne timeout
Console.WriteLine("waithandle signalled");
Console.ReadKey();
}


Mit der TPL wurde es aber auch deutlich einfacher, die Abfolge einzelner Tasks zu steuern.
Task t = new Task(() => Thread.Sleep(1000))
.ContinueWith(t => Thread.Sleep(2000));

Die Überladungen der ContinueWith Methode erlauben Dir z.B. auch, eine ContinuationTask nur dann auszuführen, wenn die vorherige Task erfolgreich beendet werden konnte, etc...

Mit .NET 4.5 wurden die Schlüsselwörter async und await in C# eingeführt, die Dir eine weitere Option eröffnen, Dein Problem zu lösen:

async Task Execute()
{
await Task.Delay(1000); // 1. Task
Console.WriteLine("Task 1 finished");

await Task.Delay(1000); // 2. Task
Console.WriteLine("Task 2 finished");
}
17.01.2013
ffordermaier 8,4k 3 9
0
Wenn es sich um eine .Net-Programmiersprache handelt kann dir vielleicht diese Artikelreihe weiterhelfen Task Parallel Library (Teil 3) von Stefan Henneken.
17.01.2013
br93roco 41 2
0
Danke erstmal für die Antworten.
Mein Fall gestaltet sich etwas komplexer. Sorry, ich hätte es gleich schreiben sollen.
Es ist so, dass keine statische Struktur von Jobs vorliegt. Die Jobs werden erst zur Laufzeit generiert. ContinueWith kommt damit wohl nicht in Frage.
WaitHandles wären eine Möglichkeit - wennn man sie identifizierbar gestalten könnte? Ich bräuchte nämlich für jeden abhängigen Task ein eigenes WaitHandle, auf das gezielt in einem anderen Job gewartet wird.

Ich hab mir inzwischen auch noch ein paar Gedanken gemacht.
Eine mögliche Lösung wäre eine übergeordnete Verwaltungskomponente, welche die Ausführung der Tasks steuert.

Eine Andere (und die werde ich wohl nehmen) ist:
Das API bietet die Möglichkeit, eine Jobliste sequentiell, asynchron sequentiell und eben auch parallel abzuarbeiten.
Ich werde erst alle Jobs, deren Ergebnis in andere Jobs einfließen muss, asynchron sequentiell abarbeiten lassen und die restlichen dann parallel.
Das ist für den Anwender des API auch wesentlich einfacher zu stemmen als wenn er sich erst mit einer Verwaltungsinstrumentation herumschlagen muss (und ich kann mir eine Menge Arbeit sparen ;-) ).
17.01.2013
Cyron 86 5
Kennst Du TPL DataFlow? Vielleicht ist das ja was für Dich...
ffordermaier 17.01.2013
BTW: Nutze für Anmerkungen bitte die Kommentarfunktion und erweitere Deine urspr. Frage, falls Du neue Informationen mit uns teilen möchtest. Durch die Bewertung verändert sich die Reihenfolge der Posts.
ffordermaier 17.01.2013
0
TPL DataFlow - ja da klingelt was. Werde ich mir anschauen.
Dankeschön. :-)
17.01.2013
Cyron 86 5

Stelle deine Parallel-Frage jetzt!