Frage

Ich habe einen ständigen Fluss bestimmter Elemente, die ich parallel verarbeiten muss, also verwende ich TPL Dataflow.Der Haken daran ist, dass die Elemente, die denselben Schlüssel haben (ähnlich wie bei einem Wörterbuch), in einer FIFO-Reihenfolge verarbeitet werden sollten und nicht parallel zueinander sein sollten (sie können parallel zu anderen Elementen mit unterschiedlichen Werten sein).

Die geleistete Arbeit ist sehr CPU-lastig und weist nur minimale asynchrone Sperren auf. Daher bestand meine Lösung darin, ein Array von zu erstellen ActionBlock<T>Es hat die Größe von Environment.ProcessorCount ohne Parallelität und posten Sie sie gemäß den Schlüsseln GetHashCode Wert.

Schaffung:

_actionBlocks = new ActionBlock<Item>[Environment.ProcessorCount];
for (int i = 0; i < _actionBlocks.Length; i++)
{
    _actionBlocks[i] = new ActionBlock<Item>(_ => ProcessItemAsync(_));
}

Verwendung:

bool ProcessItem(Key key, Item item)
{
    var actionBlock = _actionBlocks[(uint)key.GetHashCode() % _actionBlocks.Length];
    return actionBlock.Post(item);
}

Meine Frage ist also: Ist das die beste Lösung für mein Problem?Beeinträchtige ich die Leistung/Skalierbarkeit?Vermisse ich etwas?

War es hilfreich?

Lösung

Ich halte Ihren Ansatz für vernünftig, vorausgesetzt, Sie wissen, dass die Hash-Codes gut verteilt werden.

Wenn Sie einen besseren Schutz vor fehlerhaften Distributionen wünschen, können Sie eine größere Anzahl davon verwenden ActionBlocks, während der Gesamtgrad der Parallelität durch die Verwendung eines einzigen Benutzers begrenzt wird TaskScheduler von allen Blöcken gemeinsam genutzt.Sie können einen solchen Planer finden in ParallelExtensionsExtras oder auf MSDN.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top