问题
I'm playing with signalR and I want to send every 2s a little message to my clients. So I followed this tutorial, and it works good for chatting, now, I want to implement my timer. Then, I made this (ASP.NET .NET Core 3.1):
public ChatHub()
{
Debug.WriteLine("hello");
var timer1 = new Timer();
timer1.Elapsed += this.Timer1_Elapsed;
timer1.Interval = 2000;
timer1.Start();
}
private async void Timer1_Elapsed(object sender, ElapsedEventArgs e)
{
Debug.WriteLine("tick");
await SendMessage("user", "hello");
}
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
But everytime, I get this error (in this.Clients.Add...):
System.ObjectDisposedException: Cannot access a disposed object.
And I don't understand why, I checked stackoverflow, tried some solutions, but i'm already stuck.
Thank for your help.
Sample: https://github.com/Naografix/SignalRProblem
Stacktrace:
Message = "Cannot access a disposed object.\r\nObject name: 'HomeHub'."
at Microsoft.AspNetCore.SignalR.Hub.CheckDisposed()
at Microsoft.AspNetCore.SignalR.Hub.get_Clients()
at ****.HomeHub.<Timer1_Elapsed>d__1.MoveNext() in *****.Api\Hubs\HomeHub.cs:line 32
回答1:
Another way to solve your problem is create a worker to tick every 2 seconds like following:
On your ConfigureServices
services.AddHostedService<Worker>();
The worker class:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await this.hub.Clients.All.SendAsync(broadcastMethodName, "Some message...");
await Task.Delay(2000, stoppingToken);
}
}
回答2:
I can see here this:
Don't store state in a property on the hub class. Every hub method call is executed on a new hub instance.
So I decided to search how to create a service for my hub. And this is what Medium does. (Download their solution because lot of things are missing in their tutorial)
Creating a timer in my hub was a bad approach.
Solved.
来源:https://stackoverflow.com/questions/59461730/signalr-system-objectdisposedexception-with-timer