Ich habe ein ähnliches Problem mit #92. Aber ich bin mir nicht sicher, ob ich das über 5 Jahre alte Problem hätte anstoßen sollen, also erstelle ich ein neues.
Mir ist bewusst, dass das Aufrufen von Count()
für die aufgezählten Datensätze dazu führt, dass der Cursor ans Ende geht und die weitere Operation / foreach
Schleife für die Datensätze nichts zurückgibt.
Die Gliederung meines Codes ist wie folgt
````C#
var myCSV = new CsvReader(File.OpenText(txtBox_CSVFile.Text));
myCSV.Configuration.RegisterClassMap
var record = new MyRecordClass();
var allRecords = myCSV.EnumerateRecords(record);
int recordsLength = allRecords.Count<MyRecordClass>();
foreach (var r in allRecords)
{
/* some read/write operation here
*/
scannedCSVEntry++;
progress.value = scannedCSVEntry/recordsLength;
}
````
Das recordsLength
ist hier wichtig, da ich den Fortschrittsbalken aktualisieren muss, während ich den Eintrag verarbeite
Aber wie kann ich das umgehen?
Es gibt einige Möglichkeiten.
ToList
. Sie können dann mehrere Operationen mit den Daten durchführen, einschließlich Count
.Context.RawRow
, um Ihren Fortschritt zu machen.Vielen Dank,
Ich habe mich schließlich für Methode 2 entschieden.
C#
StreamReader sr = File.OpenText(txtBox_CSVFile.Text);
int recordsLength = 0;
while(sr.ReadLine() != null)
{
++recordsLength;
}
recordsLength--; // discount 1 line because there are column headers in first row.
Console.WriteLine("recordsLength : " + recordsLength);
sr.Close();
Schließt EnumerateRecords()
den Stream automatisch, nachdem alle Einträge hydratisiert wurden? Ich frage mich, ob ich Close()
aufrufen soll, nachdem ich die Funktion aufgerufen habe.
Mein Vorschlag ist, in einen using
Block einzuschließen.
using(StreamReader sr = File.OpenText(txtBox_CSVFile.Text))
{
int recordsLength = 0;
while(sr.ReadLine() != null)
{
++recordsLength;
}
recordsLength--; // discount 1 line because there are column headers in first row.
Console.WriteLine("recordsLength : " + recordsLength);
}
Wenn Sie nur den Fortschrittsbalken aktualisieren möchten, funktionierte die Verwendung von stream.Position
für mich mit großen Dateien, ohne zuerst die gesamte Datei zu lesen:
using(StreamReader sr = File.OpenText(txtBox_CSVFile.Text))
{
var csvReader = new new CsvHelper.CsvReader(sr);
while (csvReader.Read())
{
double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
}
}
es sollte auch mit GetRecords funktionieren, habe ich aber nicht getestet:
foreach(var record in csvReader.GetRecords<MyRecordClass>())
{
double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
}
Ich habe deine Lösung überprüft
foreach(var record in csvReader.GetRecords<MyRecordClass>())
{
double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
}
was bei mir nicht funktionierte.
Aber das kannst du machen
foreach(var record in csvReader.GetRecords<MyRecordClass>())
{
double progress = (double)csvReader.Context.CharPosition / csvReader.Context.CharsRead;
}
um das gewünschte Ergebnis zu erzielen
Hilfreichster Kommentar
Wenn Sie nur den Fortschrittsbalken aktualisieren möchten, funktionierte die Verwendung von
stream.Position
für mich mit großen Dateien, ohne zuerst die gesamte Datei zu lesen:es sollte auch mit GetRecords funktionieren, habe ich aber nicht getestet: