Blazor服务器应用程序中的Hangfire作业中未注入服务

发布时间:2022-06-16 / 作者:清心寡欲
本文介绍了Blazor服务器应用程序中的Hangfire作业中未注入服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

免责声明:我对C#、ASP.NET核心和依赖项注入领域非常陌生。我已经从默认模板创建了一个简单的Blazor服务器应用程序,它构建了一个模拟天气服务,并在表格中显示从中获取的数据。现在,我希望该表每隔5秒自动更新一次,为此我使用了Hangfire.AspNetCoreHangfire.MemoryStorage包。因此,我稍微修改了FetchData.razor组件,如下所示:
@page "/fetchdata"

@using WeatherTest.Data
@using Hangfire

@inject WeatherForecastService ForecastService

Weather forecast

This component demonstrates fetching data from a service.

@if (forecasts == null) {

Loading...

} else { @foreach (var forecast in forecasts) { }
Date Temp. (C) Temp. (F) Summary
@forecast.Date.ToShortDatestring() @forecast.TemperatureC @forecast.TemperatureF @forecast.Summary
} @code { private WeatherForecast[] forecasts; public async Task UpdateForecasts() { forecasts = await ForecastService.GetForecastAsync(DateTime.Now); BackgroundJob.Schedule(() => UpdateForecasts(), TimeSpan.FromSeconds(5)); } protected override async Task OnInitializedAsync() { await UpdateForecasts(); } }

这是气象服务:

using System;
using System.Linq;
using System.Threading.Tasks;

namespace WeatherTest.Data
{
    public class WeatherForecastService
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        public Task GetForecastAsync(DateTime startDate)
        {
            var rng = new Random();
            return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = startDate.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            }).ToArray());
        }
    }
}

和服务配置:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddSingleton();
    services.AddHangfire(c => c.UseMemoryStorage());
    services.AddHangfireServer();
}

问题是UpdateForecasts()OnInitializedAsync()调用时成功,但在forecasts = await ForecastService.GetForecastAsync(DateTime.Now);被Hangfire调用时失败,在forecasts = await ForecastService.GetForecastAsync(DateTime.Now);处引发以下异常:

System.NullReferenceException:‘对象引用未设置为 对象的实例。‘

WeatherTest.Pages.FetchData.ForecastService.get返回空。

在我看来,由于Hangfire工作器在另一个线程中运行,因此WeatherForecastService不会被注入。我说的对吗?是否可以从多个线程使用一个单例,或者每个线程都应该有自己的服务实例?最后,我应该如何解决这个问题?

推荐答案

以下是使用标准TimerFetchData组件。

几点:

  1. 我已在中添加了Task.Delay以模拟慢速连接并显示页面正在刷新。
  2. StateHasChanged被包装成这样await this.InvokeAsync(StateHasChanged)以确保它在UI上下文线程上运行。
  3. 实现IDisposable,因为我们有要断开连接的计时器事件处理程序。
@page "/fetchdata"
@implements IDisposable
Weather forecast

@using StackOverflow.Server.Data
@inject WeatherForecastService ForecastService

Weather forecast

This component demonstrates fetching data from a service.

@if (forecasts == null) {

Loading...

} else { @foreach (var forecast in forecasts) { }
Date Temp. (C) Temp. (F) Summary
@forecast.Date.ToShortDateString() @forecast.TemperatureC @forecast.TemperatureF @forecast.Summary
} @code { private System.Timers.Timer aTimer = new System.Timers.Timer(2000); private WeatherForecast[]? forecasts; private string btnCss => aTimer.Enabled ? "btn-danger" : "btn-success"; private string btnText => aTimer.Enabled ? "Stop" : "Start"; protected override async Task OnInitializedAsync() { aTimer.Elapsed += TimerElapsed; aTimer.AutoReset = true; aTimer.Enabled = true; forecasts = await ForecastService.GetForecastAsync(DateTime.Now); } public async void TimerElapsed(Object? sender, System.Timers.ElapsedEventArgs e) { forecasts = null; await this.InvokeAsync(StateHasChanged); await Task.Delay(500); forecasts = await ForecastService.GetForecastAsync(DateTime.Now); await this.InvokeAsync(StateHasChanged); } public void ToggleTimer() { aTimer.Enabled = !aTimer.Enabled; this.InvokeAsync(StateHasChanged); } public void Dispose() => aTimer!.Elapsed -= TimerElapsed; }

这篇关于Blazor服务器应用程序中的Hangfire作业中未注入服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持吉威生活!



[英文标题]Service not being injected within Hangfire job in Blazor Server App


声明:本媒体部分图片、文章来源于网络,版权归原作者所有,如有侵权,请联系QQ:330946442删除。