Frage

Ich bin neu in Threads und die Hilfe braucht. Ich habe eine Dateneingabe-Anwendung, die eine übertriebene Menge an Zeit benötigt, um einen neuen Datensatz einzufügen (d.h 50-75 Sekunden). So war meine Lösung eine Insert-Anweisung aus über einen Threadpool senden und ermöglicht es dem Benutzer zu beginnen, um die Eingabe von Daten für die Aufzeichnung während dieses Einsatzes, der eine neue Rekord-ID zurückzugibt, während das Insert läuft. Mein Problem ist, dass ein Benutzer getroffen speichern kann, bevor die neue ID von diesem Einsatz zurückgeführt wird.

Ich habe versucht, in einer Boolesche Variable setzen, die auf true aus diesem Thread über ein Ereignis eingestellt werden, wenn es sicher ist, zu speichern. Ich habe dann setzen in

while (safeToSave == false)  
{  
    Thread.Sleep(200)  
}  

Ich denke, dass eine schlechte Idee ist. Wenn ich das speichern Methode vor, dass Lauffläche zurückkehrt laufen, es klemmt.

Also meine Fragen sind:

  1. Gibt es einen besseren Weg, dies zu tun?
  2. Was mache ich falsch hier?

Vielen Dank für jede Hilfe.
Doug

Bearbeiten für weitere Informationen:

Es tut einen Einsatz in einem sehr großen (annähernd maximale Größe) FoxPro-Datenbank. Die Datei hat etwa 200 Felder und fast so viele Indizes auf sie.
Und bevor Sie fragen, nein, ich kann nicht die Struktur verändern, wie es hier war, bevor ich war, und es gibt eine Tonne von Code Vermächtnis schlägt es. Das erste Problem ist, um eine neue ID zu bekommen ich zuerst den max (id) in der Tabelle dann erhöhen und Prüfsumme finden muß. Das dauert etwa 45 Sekunden. Dann wird der erste Einsatz ist einfach und der Einsatz dieser neuen ID und ein enterdate Feld. Diese Tabelle ist nicht / kann nicht in eine DBC gestellt werden, so dass Regeln aus Auto-Generierung IDs und dergleichen.

@ joshua.ewer
Sie haben die proccess richtig und ich denke, für die kurzfristig Ich werde die Taste speichern nur deaktivieren, aber ich werde in Ihre Idee suchen sie in eine Warteschlange übergeben. Haben Sie alle Verweise auf MSMQ haben, dass ich auf einen Blick?

War es hilfreich?

Lösung

Alle anderen, auch Sie, adressiert die Kernprobleme (Einsatzzeit, warum Sie einen Einsatz tust, dann aktualisieren), so werde ich nur mit den technischen Bedenken mit Ihrem vorgeschlagene Lösung bleiben. Also, wenn ich den Fluss rechts:

  • Thread 1: Start der Dateneingabe für Datensatz

  • Thread 2: Hintergrund ruft DB neue Id abrufen

  • Die Taste speichern ist immer aktiviert, wenn Benutzer versuchen, vor dem Thema zu speichern 2 abgeschlossen, setzen Sie # 1 auf den Schlaf 200 ms?

Die einfachste, nicht am besten, Antwort muß nur die Taste deaktiviert, und hat das Thread ein Rückruf an einen Delegaten, die Taste ermöglicht. Sie können nicht den Aktualisierungsvorgang starten, bis Sie sicher, dass die Dinge sind in geeigneter Weise eingerichtet sind.

Obwohl, ich glaube, eine viel bessere Lösung (obwohl es übertrieben sein könnte, wenn Sie nur eine Q & D Frontend FoxPro Aufbau), wäre jene Operationen in eine Warteschlange speichern zu werfen. Der Anwender kann so schnell wie möglich eingeben, dann werden die Anforderungen gestellt in so etwas wie MSMQ und sie können asynchron in ihrer eigenen Zeit abzuschließen.

Andere Tipps

1) Viele :), zum Beispiel könnten Sie deaktivieren die Schaltfläche „Speichern“, während der Thread das Objekt einfügen, oder Sie können einen Thread Worker-Setup, die eine Warteschlange von „speichern Anfragen“ behandeln (aber ich denke, das Problem hier ist, dass der Benutzer die neu erstellte Datensatz, so deaktivieren sie die Taste vielleicht ist es besser)

ändern will

2) Ich denke, dass wir etwas mehr Code müssen in der Lage zu verstehen, ... (oder vielleicht ist ein Synchronisierungsproblem, ich bin kein Bug Fan von Threads zu)

btw, ich verstehe einfach nicht, warum ein Einsatz so nehmen sollte long..I denken, dass Sie diesen Code überprüfen sollten zuerst! <- wie Charles bereits erwähnt (sorry, dind't die Post lesen):)

Verwenden Sie einen Zukunft eher als eine rohe Thread Aktion. Führen Sie die Zukunft, ermöglicht es dem Benutzer zu tun, was sie wollen, wenn sie getroffen Speicher auf dem zweiten Datensatz, fordern Sie den Wert aus der Zukunft. Wenn der erste Einsatz bereits abgeschlossen, werden Sie die ID erhalten sofort und der zweite Einsatz wird zum Auftakt erlaubt werden. Wenn Sie noch auf der ersten Operation warten, wird die Zukunft blockieren, bis es verfügbar ist, und dann kann die zweite Operation auszuführen.

Sie sind keine Zeitersparnis, wenn der Benutzer langsamer als der Betrieb ist.

Als erstes sollten Sie wahrscheinlich herausfinden, und beheben, den Grund, warum ein Einsatz so lange dauert ... 50-75 Sekunden ist unzumutbar für jede moderne Datenbank für eine einzelne Zeile einfügen, und zeigt an, dass etwas anderes zu sein braucht adressiert, wie Indizes oder Blockierung ...

Zweitens, warum einfügen Sie den Datensatz, bevor Sie die Daten haben? Normalerweise werden die Dateneingabe-Anwendungen kodiert, so dass der Einsatz versucht nicht, bis alle erforderlichen Daten für den Einsatz von dem Benutzer gesammelt. Tun Sie dies, weil Sie versuchen, die neue Id zurück aus der Datenbank zu erhalten zuerst, und dann „Update“, um den neuen, leeren Datensatz mit den vom Benutzer eingegebenen Daten später? Wenn ja, hat fast jeder Datenbank-Anbieter einen Mechanismus, bei dem man nur einmal dem Einsatz tun, ohne die neue ID zu kennen, und hat die Datenbank die neue ID zurückkehren und ... Welche Anbieter-Datenbank verwenden Sie?

Ist eine Lösung wie diese möglich:

Pre-berechnen die eindeutigen IDs, bevor ein Benutzer selbst zu hinzufügen beginnt. Halten Sie eine Liste von eindeutigen IDs, die bereits in der Tabelle sind, aber effektiv Halter platzieren. Wenn ein Benutzer einzufügen versucht, sie zu einer der eindeutigen IDs behalten, wenn der Benutzer drückt speichern, sie nun den Platzhalter mit ihren Daten ersetzen.

PS: Es ist schwierig, dies zu bestätigen, aber das folgende Concurrency Problems bewusst sein, mit dem, was Sie vorschlagen (mit oder ohne Gewinde): User A, beginnt hinzuzufügen, Benutzer B hinzufügen startet, berechnete Benutzer A ID 1234 als der freie max ID berechnet Benutzer B ID 1234 als max freie ID. Benutzer A fügt ID 1234, Benutzer B fügt ID 1234 = Boom!

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