2 Stimmen

Sollte ich einen SqlDataReader durch Verweis übergeben oder nicht, wenn es an mehrere Threads übergeben

Neu zu c# Ich habe in dieses "Rätsel" laufen, wenn ein SqlDataReader zwischen verschiedenen Threads weitergeben. Ohne zu sehr ins Detail zu gehen, ist die Idee, einen Hauptthread zu haben, der Daten aus der Datenbank abruft (einen großen Datensatz) und dann eine Helper-Task durch diese Datensatz für Datensatz und tun einige Dinge auf der Grundlage der Inhalte dieser laufen. Es gibt keine Rückmeldung an den Datensatz, es wird einfach durchgewühlt, bis keine Datensätze mehr übrig sind. Das funktioniert gut, aber angesichts der Art der Aufgabe sollte es möglich sein, diese Aufgabe auf verschiedene Threads (CPUs) zu verteilen, um den Durchsatz zu maximieren (die Reihenfolge der Ausführung ist nicht von Bedeutung). Die Frage ist nun, ob ich ref verwenden muss, wenn ich diesen Datensatz in einem SqlDataReader übergebe oder nicht? Es läuft auf die Frage hinaus: Wenn ich das Objekt ohne Angabe von ref weitergebe, werden dann nicht neue Kopien im Speicher erstellt und die Datensätze n-mal verarbeitet? Oder riskiere ich nicht, dass die Position des Datensatzes nach vorne verschoben wird, während noch nicht alle Felder vollständig gelesen wurden? Letzteres scheint eher ein Problem des "Datenrennens" zu sein und ist wahrscheinlich durch den lock()ing-Mechanismus abgedeckt (oder nicht?).

Mein erster Gedanke zu diesem Problem war, dass es nicht wirklich weh tut, die Variable mit ref zu übergeben, aber wie ein Kollege es ausdrückte: "Du brauchst ref nur, wenn du etwas falsch machst" =) Außerdem schränkt die Verwendung von ref die Möglichkeit ein, eine Using()-Konstruktion zu verwenden, was auch nicht sehr schön ist. Ich habe also ein "einfaches" Projekt erstellt, das den gleichen Ansatz verfolgt, aber ohne die ref-Notation. Die bisherigen Tests zeigen, dass es auf einem Core2Duo (2cpu) mit einer beliebigen Anzahl von Threads einwandfrei funktioniert, aber ich bin immer noch ein bisschen misstrauisch... Was denken Sie als Experten darüber? Ref verwenden oder nicht?

Sie finden das Testprojekt aquí da ich sie anscheinend nicht direkt in diese Frage hochladen kann?!?

ps: es ist nur ein Test-Projekt und ich bin neu in c#, so bitte sanft auf mich sein, wenn Aufschlüsselung der Code =P

5voto

Dave Markle Punkte 91733

Geben Sie SqlDataReader nicht an mehrere Threads weiter. Die Dokumentation sagt diese Klasse ist nicht thread-sicher.

Selbst wenn es wäre, würden Sie alle Arten von Timing-Probleme, die sich aus dieser, vor allem, wenn es Zeit, Ihre SqlDataReader zu entsorgen kommt haben. Fügen Sie zu, dass die Tatsache, dass SqlDataReader bereits Daten in auf einem anderen Thread streamt, und ich denke, dass Sie verfrüht optimieren.

1voto

deroby Punkte 5719

Vielen Dank für die vielen Kommentare, ich hätte nicht mit so vielen Reaktionen in so kurzer Zeit gerechnet! (Habt ihr denn nichts Besseres zu tun? =) Leider weisen die meisten von ihnen darauf hin, dass mein Ansatz fehlerhaft ist =/

Wie dem auch sei, in der Annahme, dass mein derzeitiger Ansatz zumindest einen gewissen Lernvorteil bietet, hatte ich gehofft, eine Antwort auf die Frage "Ref verwenden oder nicht" zu finden. Nachdem ich mich den ganzen Tag durch zahlreiche Fragen und Antworten, Foren und Blogs gewühlt habe, bin ich schließlich auf diese Antwort gestoßen (NACHDEM ich meine Frage gepostet hatte, typisch) aquí . Von dem, was in dieser Antwort gesagt wird, ich denke, es ist sicher zu schließen, gibt es keine Notwendigkeit, ref zu verwenden, weil obwohl es "durch Wert" übergibt, ich jetzt verstehen, es tatsächlich den Zeiger auf dem Stapel damit alle Änderungen an das Objekt (z.B.. Verschieben auf den nächsten Datensatz) auf die gleiche Instanz des Objekts, die getan werden, was ich brauchte Rückversicherung aus.

Solange ich nicht so etwas Dummes tue wie zu glauben, dass ein anderer Thread das Objekt z. B. durch das Ergebnis eines anderen SqlCommand.ExecuteReader() ersetzen kann, sollte alles in Ordnung sein.

Wenn ich die obigen Kommentare lese, verstehe ich jetzt auch besser, was Mitch Wheat meinte mit seiner Bemerkung

die Verwendung von ref (im Wesentlichen ein Verweis auf einen Verweis)

Tut mir leid, dass ich es nicht früher "verstanden" habe...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X