0

I am currently trying to use a Timer (System.Timers) within a Blazor component to update an entity using an Injected DBContext. However when it reaches the Save Changes method it simply shows the following error

enter image description here Disposed Exception

Here is the my Startup.cs file DbContext section: Startup.cs

My Blazor Component CS looks like this: Blazor Component

What I think the Problem Is

I think the problem is that the Timer class is on a different thread and therefore isn't in scope to access to the DbContext.

What I don't know is, if I am right, how to pass the DbContext properly to the Timer or how to call the Save Changes method from the main thread.

I did try to use a DBContextPool (as shown below) but it doesn't work. I am guessing it's still due to the thread being different from the main thread.

DbContextPool

If you need any more details please just let me know so I can gather the exact details.

Update 1 07/20/2020

I attempted to move the logic into a service. That service then has a DbContext injected into it however I got the same error message but the error happened in the new ActionService class.

Here is the new ActionService

enter image description here

And here is the Startup.cs change

enter image description here

Here is the Blazor Component Update

enter image description here

Ben
  • 361
  • 2
  • 13
  • Please [edit] your question to include code and errors as **text** ([using code formatting](http://stackoverflow.com/editing-help#code)), not images. Images are problematic for [many reasons](https://meta.stackoverflow.com/a/285557), including that they don't allow copy-pasting text for testing or searching. – Cody Gray - on strike Jul 20 '20 at 22:10

1 Answers1

1

The error message indicates your DbContext was disposed of before your timer fires. It's not related to the thread the code executes on (though as a separate issue, DbContext instances are not thread-safe).

I have not used Blazor so might miss something specific to it, but you might consider having your timer instantiate a new class that has a DbContext injected into it, passing in whatever data is needed to update the database.

You might also look at configuring your class lifetime to be scoped. The downside is that you would hold an instance of your DbContext for each user connected to your service.

Eric J.
  • 147,927
  • 63
  • 340
  • 553
  • 1
    I haven't tried your solution yet however I feel fairly confident about it. I am going to try your "Service" class and have my DBContext injected. I will confirm your answer once I am able to verify – Ben Jul 20 '20 at 20:22
  • Have a peak at my update on the original post. I think that is what you were suggesting. However it appears to give me the exact same error message. Hopefully I did what you were going for. – Ben Jul 20 '20 at 21:41
  • Your ActionService is still instantiated within the lifetime of your original object, so it is also disposed when your original object is disposed. – Eric J. Jul 21 '20 at 02:54
  • Have a look at this https://stackoverflow.com/questions/49747931/server-side-timer-with-dbcontext – Eric J. Jul 21 '20 at 03:08
  • 1
    That did the trick! Thank you very much. I have marked this as the answer to my question. – Ben Jul 21 '20 at 17:20
  • If you are using .Net 5 then you can also try to use DbContextFactory as that was made for something like this. – Ben Jul 23 '20 at 20:42