blazor - 如何在 Blazor 应用程序中制作计时器泄漏证明?
问题描述
我已经在 stackoverflow C# 计数器中发布了一个问题的答案,以计数到目标数字。这是答案:
您可以创建一个可以在很多场合为您服务的计时器服务:
创建服务类:
public class BlazorTimer
{
private Timer _timer;
internal void SetTimer(double interval)
{
_timer = new Timer(interval);
_timer.Elapsed += NotifyTimerElapsed;
_timer.Enabled = true;
_timer.Start();
}
private void NotifyTimerElapsed(object sender, ElapsedEventArgs e)
{
OnElapsed?.Invoke();
}
public event Action OnElapsed;
}
将服务添加到 DI 容器中,在 Program.Main 方法中,作为瞬态:
builder.Services.AddTransient(config =>
{
var blazorTimer = new BlazorTimer();
blazorTimer.SetTimer(1000);
return blazorTimer;
});
用法
@page "/"
@implements IDisposable
@inject BlazorTimer Timer
@count.ToString()
@code{
private int count = 0;
protected override void OnInitialized()
{
Timer.OnElapsed += NotifyTimerElapsed;
base.OnInitialized();
}
private void NotifyTimerElapsed()
{
// Note: WebAssembly Apps are currently supporting a single thread, which
// is why you don't have to call
// the StateHasChanged method from within the InvokeAsync method. But it
// is a good practice to do so in consideration of future changes, such as
// ability to run WebAssembly Apps in more than one thread.
InvokeAsync(() => { count++; StateHasChanged(); });
}
public void Dispose()
{
Timer.OnElapsed -= NotifyTimerElapsed;
}
}
然而,有人告诉我
BlazorTimer 正在泄漏 _timer。定时器是 IDisposable
在 Blazor 组件中实现的 Dispose 方法中取消订阅事件处理程序会导致 BlazorTimer 泄漏 _timer。实际上我并不完全理解“BlazorTimer 正在泄漏 _timer。Timer 是 IDisposable”,所以让我问一下,我怎样才能防止计时器泄漏,但在实现的 Dispose 方法中使用代码取消订阅事件处理程序Blazor 组件?除了跳过事件处理程序的取消订阅之外,还有什么方法可以防止这种泄漏。
解决方案
BlazorTimer 应该实现 IDisposable。BlazorTimer Dispose 方法应停止计时器、取消订阅 Elapsed 事件并释放计时器。
问题的根源在于您的 BlazorTimer 设置为瞬态服务。因此,对于每个新请求,您都会获得带有新 .Net 计时器的新 BlazorTimer 对象,这些计时器永远不会被正确处理
推荐阅读
- regex - 正则表达式仅匹配“第 1 组”。而不是“完全匹配”
- azure - 使用客户端凭据流,无需从同一租户内的任何应用程序委托访问即可生成访问令牌
- mariadb - 寻求仅在一个 DC 中实施备份的解决方案
- amazon-web-services - 使用 AWS SQS 的最有效方式(使用 Golang)
- c# - 使用 python c-api 调用 PyErr_Print 后如何访问 sys.stderr
- heroku - 使用 @sentry/webpack-plugin 和 heroku 的哨兵
- excel - 为什么 Object 会抛出 Variant 没有的错误?
- amazon-s3 - 将 Amazon S3 限制为 CloudFront 和 http 引荐来源网址
- java - onPause 中的 unregisterReceiver(receiver) 导致接收方不注册
- regex - 正则表达式匹配换行符后的所有内容