Frage

Gibt es einen sequentiellen Zahlengenerator auf Systemebene auf Systemebene? Datetime.now.ticks wird es nicht tun, da die Vorgänge, die ich manchmal mehr als einmal pro Tick stattfindet.


Erfordernisserklärungen:

  • Prozess Agnostisch - Es gibt wirklich nur einen Prozess, der darauf zugreifen würde.
  • Leistung ist kritisch! Hier

Es müsste eines der folgenden sein:

  • Eine 4-Byte-sequentielle Nummer, die jede Zecke zurücksetzt
  • Eine 12 -Byte -sequentielle Zahl - im Wesentlichen 4 Bytes Granularität zu einer DateTime hinzuzufügen
War es hilfreich?

Lösung

Keine, die dafür bestimmt sind, aber Sie könnten verwenden System.Diagnostics.performanceCounter. Sie können auch die Registrierung verwenden, müssen jedoch die Prozesse serialisieren, die Lese-/Schreibzugriff abrufen.

System.Diagnostics.PerformanceCounter pc 
    = new System.Diagnostics.PerformanceCounter("SeqCounter", "SeqInstance");
long myVal=pc.Increment();

Bearbeiten

Je mehr ich darüber nachdenke, ich denke, das könnte eine schöne Lösung sein. Inkrement erhöht den Zähler durch einen Atombetrieb um 1, der alle Prozesse auf einem System abrufen sollte.

Bearbeiten

Basierend auf Ihren Änderungen würde ich nicht empfehlen, einen Leistungsschalter zu verwenden. Ein Leistungsschalter war eine Möglichkeit, mehrere Prozesse zu vergrößern. Ich bin mir nicht sicher, wie das interne Implemention codiert wird.

Warum können Sie nicht einfach eine statische Variable verwenden und inkrementieren? Sie müssen etwas sperren, wenn Sie möchten, dass dies Threadsafe ist.

System.Threading.Interlocked.increment

Zu Ihrer Information: Wenn Sie die lange Version auf einem 32 -Bit -System verwenden, ist Nessecarilly nicht sicher.


Bearbeitung, um das von mir verwendete Implementierung zu zeigen (DS):

public static class Int32Sequencer
{
    private static Int32 lastSequence = Int32.MinValue;
    private static Object lockObject = new Object();
    public static Int32 GetNextSequence()
    {
        lock (lockObject)
        {
            unchecked { lastSequence++; }
            return lastSequence;
        }
    }
}

Andere Tipps

Eine Richtlinie ist so nah wie Sie bekommen, aber diese sind "einzigartig" und nicht unbedingt sequentiell. Wenn Sie auf der Systemebene wirklich sequentiell über mehrere Prozesse hinweg möchten, müssen Sie wahrscheinlich Ihre eigenen rollen.

BEARBEITEN:

OK, also von Ihren neuen Anforderungen werde ich davon ausgehen:

  1. Nur ein Prozess muss die Arbeit erledigen
  2. Sie beitreten an einer Datenbank

Hier ist also, was ich empfehlen würde:

  1. Fragen Sie beim Start des Prozesses den DB für den letzten (größten) Wert (0, wenn keine existiert).
  2. Verwenden Sie für jede DB -Zeile einen einfachen Langen und Inkrement. Sie möchten aufgrund Ihrer hohen Datenrate in Chargen einfügen.

Das sollte es tun. Halte es einfach. Dies hat keine Schlösser, einen leichten (vernachlässigbaren) Treffer beim Start und sequentielle Zahlen in Ihrer DB. Dieser Algorithmus ist auch prozess-agnotisch, solange Sie nur einen Prozess ausführen.

Ich denke, das Nächste ist ein GUID, was, wie Sie sicher sind, bestenfalls nur teilweise sequentiell sind.

Hier gibt es einen Artikel, der einige Details für SQL Server enthält:Sequentielle Guids in SQL Server Diese Technik wird verwendet, um Seitenaufenthalte aufgrund der Zufälligkeit der GUIDs zu minimieren. Vielleicht gibt dieser Link Ihnen einige Hinweise oder Ideen.

Ich denke, wir müssen ein bisschen mehr darüber wissen, wonach Sie suchen. Können Sie Ihre Frage ein wenig klären? Insbesondere macht der Service ...

  • Müssen Sie über alle Prozesse, einen Prozess oder einen bestimmten Benutzer hinweg arbeiten?
  • Müssen die Zahlen eindeutig oder nur sequentiell sein?

Basierend auf Ihrer Frage scheinen einige verschiedene Artikel zu sein, nach denen Sie möglicherweise suchen.

Benötigen Sie eine sequentielle Gruppe von Zahlen über alle Prozesse auf dem System hinweg

Afaik, es gibt keinen solchen Dienst. Man sollte ziemlich einfach zu schreiben sein, aber es ist schwierig, alle Prozesse in allen Prozessen zu funktionieren.

Benötigen Sie eine eindeutige sequentielle Gruppe von Zahlen über alle Prozesse auf dem System hinweg

Leichte Variation der ersten Frage. Ein solcher Dienst existiert nicht, weil es unmöglich wäre, implementiert zu werden. Es gibt keine Möglichkeit, eine eindeutige sequentielle Nummer mit den integrierten Datentypen zu gewährleisten, nur weil der Wert irgendwann überflutet und Sie eine doppelte Zahl hinterlässt.

Benötigen Sie eine Methode, um eindeutige Werte im System zu erhalten

Da mehrere andere Benutzer erwähnt haben, ist die beste Wahl eine System.guid -Instanz. Sie können eine neue mit gud.newguid () erstellen. Für fast alle Zwecke können sie als einzigartig angesehen werden, sind aber nicht sequentiell.

Ich mag die Datenbankoption einfach aus Sicherheit. Stellen Sie sicher, dass Sie einen Monster SQL -Server mit einer Bandbreite zwischen Ihren Servern mit genügend Speicher installieren. Ein ähnliches System, das dies ähnelt, wurde bei der ersten Firma implementiert, für die ich jemals gearbeitet habe (bevor ich sogar Programmierer wurde), und es war sehr zwielichtig. Sie können kämpfen, um dies zu skalieren.

Eine andere Option wäre, eine Singleton -Funktion in Ihren Code zu implementieren ... vorausgesetzt, nur eine Anwendungsdomäne ruft sie auf. Kann etwas schneller sein als eine Datenbankreise. Wenn Sie dieses Zeug trotzdem in der Datenbank protokollieren wollen ... was ist mit der Kombination der beiden ... Führen Sie einen Singleton für Geschwindigkeit aus und schreiben Sie dann in die Datenbank, wenn die Ressourcen dies zulassen.

Wenn die sequentielle Anforderung nicht so stark ist, wäre eine Richtlinie die beste Wahl.

Es gibt keine Möglichkeit, eine einzelne sequentielle Serie ohne Sperren zu erhalten. Es spielt keine Rolle, welchen Mechanismus Sie verwenden, um den nächsten Wert zuzuweisen - einen Leistungszähler, eine statische Variable, was auch immer - Wenn zwei Threads gleichzeitig den nächsten Wert benötigen, muss man auf dem anderen warten.

Das erste, was ich tun würde, ist ein Testprogramm zu schreiben, das eine große Anzahl von Threads hervorgebracht hat, die jeweils eine Locking -Increment -Funktion bezeichneten, wie z. B. die von Daniel Schaffer gepostet. Dadurch können Sie den Schwellenwert finden, an dem Ihre Bewerbung zu verprügeln beginnt - wo sie mehr Zeit damit verbringt, darauf zu warten Monitor.Enter als etwas anderes zu tun.

Wenn sich herausstellt, dass dies ein Problem ist - und ich würde wetten, dass wenn die Volumes, über die Sie sprechen, real sind -, sollten Sie jeden Thread dazu bringen, seinen eigenen sequentiellen Zähler beizubehalten, was Sie tun können, indem Sie das Zählerfeld markieren mit dem ThreadStaticAttribute. Sie können dann eindeutige Kennungen aus einer Kombination aus der ID des Threads und des Zählers erzeugen.

Dieser Ansatz funktioniert nicht, wenn Sie keinen Thread -Pool verwenden (da der Zähler stirbt, wenn der Faden, zu dem er gehört, tut). Sie möchten wahrscheinlich auch den Startup der Anwendung zu einem Teil der zusammengesetzten ID machen, damit Sie die Thread -Zähler nicht in einen dauerhaften Speicher schreiben müssen. (Wenn Sie dies nicht getan haben, wenn Sie den Server neu gestartet haben, werden die Threads wieder auf Null generiert, und wenn Ihre Anwendung einen Thread mit derselben ID wie eine frühere Instanz erstellt hat, erhalten Sie doppelte Bezeichnungen.)

Dies ist offensichtlich nicht trivial zu schreiben (oder, was noch wichtiger ist), also würde ich auf jeden Fall empfehlen, zu beweisen, dass es zuerst notwendig ist.

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