Cannot access a disposed object : DataContext

146 Views Asked by At

I'm using TCPClient to connect to device and get some data as a strings, then I'm trying to save data to DB and getting

"Cannot access a disposed object" error."

Maybe problem is because I'm trying to save to DB from async callback function? Please take a look, here are two functions: first one gets network stream, already connected to the device and starts reading data, second one is callback:

private void ReadDataAsync(NetworkStream nwStream)
        {
            byte[] buffer = new byte[1024];

            messageStream mStream = new messageStream(nwStream, buffer);

            if (nwStream.CanRead)
            {
                Console.WriteLine("Starting async");
                nwStream.BeginRead(buffer, 0, buffer.Length,
                    new AsyncCallback(OnReadEndAsync), mStream);
            }

            else
            {
                Console.WriteLine("Cannot read stream");
            }
        }

        private void OnReadEndAsync(IAsyncResult result)
        {
            String message = "";

            messageStream mStream = (messageStream)result.AsyncState;
            int incDataSize = mStream.nwStream.EndRead(result);

            message = Encoding.ASCII.GetString(mStream.buffer, 0, incDataSize);
            List<Event> events = new List<Event>();
            events = ProcessMessage(message);
            if(events.Any())
                 _repo.saveEventsToDB(events);
            if (mStream.nwStream.CanRead)
            {
                mStream.nwStream.BeginRead(mStream.buffer, 0, mStream.buffer.Length,
                    new AsyncCallback(OnReadEndAsync), mStream);
            }
        }
1

There are 1 best solutions below

0
On

Finally found a solution!

So problem was that I used DataContext dependancy, which was injected in the controller constructor - and it was disposed after HTTP request was completed.

So solution is to inject dependancy manually in the function itself, which needs access to the database:

  1. Inject scope factory IServiceScopeFactory scopeFactory in the controller constructor.

  2. Add this to my function where I need access to DBcontext:

    using (var scope = _scopeFactory.CreateScope()) { var context = scope.ServiceProvider.GetRequiredService(); ... }