Search code examples
c#asp.net-core.net-coreasp.net-core-signalr

SignalR Core throws disposed exception


I have a hub and it's set up like this:

public class MainHub : Hub<IMainHub>
{
    private readonly IJobManager jobManager;

    public MainHub(
        IJobManager jobManager)
    {
        this.jobManager = jobManager;

        this.jobManager.JobUpdated += async (s, e) =>
        {
            await Clients.Group(e.Group).JobUpdate(e.Job);
        };
    }
]

The IJobManager is a class that use SqlDependency to monitor changes on a table and is registered as a singleton. The hub works fine when not subscribed to the JobUpdated event (or the event is not fired).

But when the event is fired, I get the following exception:

Cannot access a disposed object. Object name: 'MainHub'.

Why does this error occur?

And if I swap the DI in that I inject the hub into the job manager (as this class is a singleton), I assume that the hub will not be disposed.


Solution

  • It looks like your problem is that you are not deregistering the event listener when the MainHub has done it's work. You have no control over how long one instance of that one lives...

    Don't use an anonymous function and deregister the event listener.

    public class MainHub : Hub<IMainHub>
    {
        private readonly IJobManager jobManager;
    
        public MainHub(
            IJobManager jobManager)
        {
            this.jobManager = jobManager;
    
            this.jobManager.JobUpdated += OnJobUpdated;
        }
    
        private async void OnJobUpdated(object s, Event e)
        {
           await Clients.Group(e.Group).JobUpdate(e.Job);
        }
    
        protected override void Dispose(bool disposing)
        {
            if (disposing) {
              this.jobManager.JobUpdated -= OnJobUpdated;
            }
            base.Dispose(disposing);
        }
    }
    

    You will need to fix the signature of the function there, since I don't know the real one.