ObjectDisposedException thrown when trying to save files to a DbContext

1

I am uploading a text file and writing each split line to a database. The file has over a million lines. The upload and saving to the database works but breaks after the save on the await _context.SaveChangesAsync(); line with the following error

System.ObjectDisposedException HResult=0x80131622 Message=Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. Object name: 'LanternDBContext'.

public async void ImportUploadTextFile(string fileName)
{
    string rootFolder = _hostingEnvironment.WebRootPath;

    using (StreamReader sr = new StreamReader(Path.Combine(rootFolder + "/UploadedFiles/", fileName)))
    {
        List<UploadTextFile> InputList = new List<UploadTextFile>();

        while (sr.Peek() >= 0)
        {
            string str;
            string[] strArray;
            str = sr.ReadLine();

            strArray = str.Split(' ');
            InputList.Add(new UploadTextFile
            {

                CorpCode = strArray[0],
                AccountCode = strArray[1],
                CostCenter = strArray[2]

            });
        }

        _context.UploadTextFile.AddRange(InputList);


    }
    await _context.SaveChangesAsync();
}
c#
asp.net-core
entity-framework-core
asked on Stack Overflow Mar 13, 2019 by Narian Naidoo • edited Mar 13, 2019 by Panagiotis Kanavos

2 Answers

2

async void is only meant for event handlers. It fires off a fire-and-forget task that can't be awaited or monitored and could still be running long after an ASP.NET request terminates and its context gets disposed.

The proper syntax for an asynchronous method that doesn't return anythig is async Task. The method signature should change to

public async Task ImportUploadTextFile(string fileName)

and whoever calls ImportUploadTextFile should await it. If it's called in a controller action, the action itself should be asynchronous and await it, eg :

public async Task Post(whatever)
{
    ....
    await ImportUploadTextFile(fileName);
}
answered on Stack Overflow Mar 13, 2019 by Panagiotis Kanavos • edited Mar 15, 2019 by Panagiotis Kanavos
1

Your db context is disposed by the time you trying to save changes. Probably your method

ImportUploadTextFile

is used out of the proper scope.

answered on Stack Overflow Mar 13, 2019 by Akmal Salikhov

User contributions licensed under CC BY-SA 3.0