2010-12-31 6 views
4

Etwas von einem interessanten hier denke ich. Ich habe eine Klasse, die für das "Multiplexen" einer Anzahl von Verarbeitungsoperationen auf eine feste Anzahl von Threads zuständig ist. Der typische Fall ist eine Art Producer/Consumer-Problem, bei dem jede Operation aus einem WaitHandle (in diesem Fall dem Semaphor, der die Anzahl der in der Warteschlange enthaltenen Elemente verfolgt) und einem zu aktivierenden Delegaten besteht.Kombinieren Wartegriffe?

Zum Beispiel, wenn ich zwei Produzenten (A und B) habe, produzieren die Artikel in zwei separate Warteschlangen. Anstatt zwei Consumer-Threads für jeden Producer (A1, A2, B1, B2) zu erstellen, multiplexe ich die vier Konsumenten-Threads auf zwei Threads. Der Code für diese „Multiplexer“ läuft so etwas wie dieses (vereinfacht ein Bit):

WaitHandle[] waitHandles = new WaitHandle[2]; 
waitHandles[0] = NumberOfItemsFullInProducerAQueue; 
waitHandles[1] = NumberOfItemsFullInProducerBQueue; 
while(true) 
{ 
    int index = WaitHandle.WaitAny(waitHandles); 
    if(index == 0) 
    { 
     // handle the item from queue A 
    } 
    else 
    { 
     // handle the item from queue B 
    } 
} 

Ich versuche, dieses Konzept auf ein etwas komplizierteres Beispiel zu erweitern, wo eine Aktion mehrere Warte benötigen Griffe zufrieden zu sein bevor es ausgeführt wird. Ich frage mich, ob es einen WaitHandle.Combine (waitHandle1, waitHandle2) Aufruf gibt, den ich machen kann, um zwei Wait Handles zu einem einzigen Wait Handle zu kombinieren. Das Endergebnis wäre so etwas wie:

A,B,C,D are waitHandles 
E = Combine(A, B) 
F = Combine(C, D) 
waitHandles = { E, F } 

while(true) 
{ 
    int index = WaitHandle.WaitAny(waitHandles); 
    if(index == 0) 
    { 
    } 
    else 
    { 
    } 
} 

Extra Punkte?

Obwohl keine Voraussetzung, kann es auch wirklich nett sein, wenn sich die Kombinationen von Waithandles überschneiden könnten. Zum Beispiel so etwas wie dieses:

A,B,C are waitHandles 
    D = Combine(A, B) 
    E = Combine(A, C) 
    waitHandles = { D, E } 
    // same as above from here 

Danke für Ihre Hilfe SO

+1

Zusätzliche Punkte? Ich werde dann auf das Kopfgeld warten. –

+0

Habe ich irgendeine Art von SO Community no-no damit gemacht? (Ein weiterer Beweis dafür, dass das Internet Sarkasmus-Skripte benötigt, um Situationen wie diese eindeutig zu machen) ... – LorenVS

+0

@LorenVS Ich denke, worauf Hans hinweist, ist, dass man diese Extrapunkte tatsächlich über eine Prämie vergeben kann, eher weil sie metaphysisch sind. Was bedeutet und für "Extrapunkte" eigentlich eigentlich? Können wir mit dem Hamster spielen? –

Antwort

1

Sie sollten erwägen in die neue Barrier Klasse in .NET 4 TPL (zurückportiert bis 3,5 als Teil Reactive Extensions suchen Es ist. Speziell für die von Ihnen beschriebenen Szenarien entworfen, bei denen Sie die Ausführung blockieren müssen, bis mehrere kooperierende Aufgaben einen Prüfpunkt erreicht haben Sie können auch das Task-System verwenden, um komplexe Fortführungspfade zu erstellen, wobei je eine Task abhängig von einer ersten Aufgabe zwei vorausgeht Vervollständigen und, falls Ausnahmen zu irgendeinem Zeitpunkt auftreten, das Zusammenführen und Melden von Ausnahmen an einem zentralen Ort.

+0

Hmm ... ich dachte, Aufgaben wären die Lösung, ich muss vielleicht einige Übergänge machen, um sie zu verwenden mehr ... – LorenVS

+1

Das Beispiel in der verknüpften MSDN-Seite der Barrier-Klasse verwendet die farbenprächtigste Sprache, die ich je gesehen habe auf MSDN. Die Verwendung von Phrasen wie "D'oh!", "Nope - änderte meine Meinung" und "hunky-dory" lassen mich denken, dass es von einem Entwickler und nicht von einem technischen Autor geschrieben wurde, was eine menschliche Note hinzufügt (obwohl es für ein breiteres internationales Publikum weniger appellieren könnte, wo solche Phrasen für die Lesbarkeit nachteilig sein könnten). –

+0

@LorenVS, ich habe es genossen, mit Tasks an aktuellen Projekten zu arbeiten. Es gibt eine Menge Tiefe für die TPL, besonders wenn Sie sich mit der abhängigen Taskfortsetzung beschäftigen (Task C erfordert, dass A und B zuerst erfolgreich abgeschlossen werden, möglicherweise parallel), kooperative Löschung und die Art und Weise, wie sie die Ausnahmebehandlung für Sie verwaltet. Ich habe im Laufe der Jahre viele, viele Teile von Threading-Klempner-Code auf verschiedene Arten für verschiedene Projekte codiert, also ist es schön, diese Funktionalität endlich in der BCL zu sehen. –