Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CsvHelper throws System.ObjectDisposedException on second iteration

I'm trying to write a method that will read all the CSV files from inside a ZIP file as submitted as an IFormFile through an HttpRequest.

I'm using CsvHelper to read the files contents using this code:

using (var archiveStream = zip.OpenReadStream())
{
    using (var archive = new ZipArchive(archiveStream))
    {
        foreach (var entry in archive.Entries)
        {
            using (var entryStream = entry.Open())
            {
                using (TextReader reader = new StreamReader(entryStream))
                {
                    using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
                    {
                        using (var dataReader = new CsvDataReader(csv))
                        {
                            while (dataReader.Read())
                            {
                                object[] values = new object[dataReader.FieldCount];
                                dataReader.GetValues(values);
                                // do stuff with object[]
                            }
                        }
                    }
                }
            }
        }
    }
}

However, on the second iteration of the foreach I get System.ObjectDisposedException: 'Cannot access a closed file.' when it gets to var dataReader = new CsvDataReader(csv).

It's not clear to me which "file" it thinks is disposed. How can I keep this stream open throughout the full loop?

Possibly relevant information: This is running inside a Task<> launched from an ApiController.

like image 768
Paul Avatar asked Dec 21 '25 14:12

Paul


1 Answers

  • This is running inside a Task<> launched from an ApiController.
  • Are you awaiting the task?
  • I am not

The request data will be automatically disposed by ASP.NET when the request processing will finish (i.e. when the action result will be executed and response will be send to the client), including the request body, resulting in the stream returned by IFormFile.OpenReadStream being disposed too. Since you are not awaiting the processing task the request processing can be finished before the task hence the exception.

You need either to await the task processing the stream or alternatively - download all the data (into memory or in some kind of temp file) and process it "offline" (either via task or some kind of background worker pipeline - see Background tasks with hosted services in ASP.NET Core, Quartz.NET, Hangfire).

like image 170
Guru Stron Avatar answered Dec 23 '25 02:12

Guru Stron



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!