[英]SignalR: System.ObjectDisposedException with timer
I'm playing with signalR and I want to send every 2s a little message to my clients.我正在玩signalR,我想每2秒向我的客户发送一条小消息。 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 ):
然后,我做了这个( 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... ):但每次,我都会收到此错误(在this.Clients.Add... 中):
System.ObjectDisposedException: Cannot access a disposed object.
System.ObjectDisposedException:无法访问已处理的对象。
And I don't understand why, I checked stackoverflow, tried some solutions, but i'm already stuck.我不明白为什么,我检查了 stackoverflow,尝试了一些解决方案,但我已经被卡住了。
Thank for your help.感谢您的帮助。
Sample: https://github.com/Naografix/SignalRProblem示例: https : //github.com/Naografix/SignalRPproblem
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
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.
这就是Medium所做的。 (Download their solution because lot of things are missing in their tutorial)
(下载他们的解决方案,因为他们的教程中缺少很多东西)
Creating a timer in my hub was a bad approach .在我的集线器中创建计时器是一种糟糕的方法。
Solved.解决了。
Another way to solve your problem is create a worker to tick every 2 seconds like following:解决问题的另一种方法是创建一个工作人员,每 2 秒打勾一次,如下所示:
On your ConfigureServices
在您的
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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.