Hi I have a program to parse a CSV and fill it into a DataGridView.
When I'm doing it like this it works great:
openFileDialog1.Filter = "CSV Files(*.csv)|*.csv";
openFileDialog1.FilterIndex = 1;
openFileDialog1.RestoreDirectory = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
txtCsvSource.Text = openFileDialog1.FileName;
Encoding iso = Encoding.GetEncoding("ISO-8859-1");
using (CachedCsvReader csv = new CachedCsvReader(new StreamReader(txtCsvSource.Text, iso), true))
{
csv.MissingFieldAction = MissingFieldAction.ReplaceByEmpty;
dataGridView1.DataSource = csv;
}
}
But when Im doing it like this:
openFileDialog1.Filter = "CSV Files(*.csv)|*.csv";
openFileDialog1.FilterIndex = 1;
openFileDialog1.RestoreDirectory = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
txtCsvSource.Text = openFileDialog1.FileName;
dataGridView1.DataSource = QrFunctions.parsecsv(txtCsvSource.Text);
dataGridView1.Update();
}
with the QrFunctions.parsecsv being like:
public CachedCsvReader parsecsv(string csvpath)
{
Encoding iso = Encoding.GetEncoding("ISO-8859-1");
using (CachedCsvReader csv = new CachedCsvReader(new StreamReader(csvpath, iso), true))
{
csv.MissingFieldAction = MissingFieldAction.ReplaceByEmpty;
return csv;
}
}
the DataGridView is empty... why? I simply have no idea :-( I just wanted to use this function to parse in another Class, so I created the class QrFunctions.
Try this.
public CachedCsvReader parsecsv(string csvpath)
{
Encoding iso = Encoding.GetEncoding("ISO-8859-1");
CachedCsvReader csv = new CachedCsvReader(new StreamReader(csvpath, iso), true)
{
csv.MissingFieldAction = MissingFieldAction.ReplaceByEmpty;
return csv;
}
}
Please remember to dispose of the object yourself, since I have removed the using statement or implement the IDisposable pattern
Thanks to @MartiniMoe for constructive comments.
Alykhalid's answer was almost correct except it looks like the Dispose
method of the CachedCsvReader
is calling Dispose
on the StreamReader
.
All a using statement is, is syntactic sugar for the following code:
try
{
var yourObject = new SomeIDisposable();
// Some code using yourObject
}
finally
{
yourObject.Dispose();
}
So the using around CachedCsvReader
is calling the Dispose() method of the reader, which I'm guessing looks something like:
void Dispose()
{
streamReader.Dispose();
}
So once you are outside the using block, dispose has been called on the StreamReader
and even when you copy your csv reader reference to an object outside the using, your stream itself has been closed so your DataGridView
receives no data.
As you have found, this can be fixed by removing the using statement, but this has the downside that you are now not closing your stream, which can have some undesired effects.
To follow safest practices you should either:
Put the using statement back in your helper function but read the stream inside the using - hopefully the CSV reader can be forced to read straight away and return some sort of List of csv rows. Then you just return the list rather than the CSV reader. Your code would look something like:
public List<CSVRows> parsecsv(string csvpath) { Encoding iso = Encoding.GetEncoding("ISO-8859-1"); using (CachedCsvReader csv = new CachedCsvReader(new StreamReader(csvpath, iso), true)) { csv.MissingFieldAction = MissingFieldAction.ReplaceByEmpty; // I have no idea what this method is but if it exists it could be called ToList or Read return csv.ToList<CSVRows>(); } }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.