Service not being injected within Hangfire job in Blazor Server App(Blazor服务器应用程序中的Hangfire作业中未注入服务)
                            本文介绍了Blazor服务器应用程序中的Hangfire作业中未注入服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
                        
                        问题描述
免责声明:我对C#、ASP.NET核心和依赖项注入领域非常陌生。我已经从默认模板创建了一个简单的Blazor服务器应用程序,它构建了一个模拟天气服务,并在表格中显示从中获取的数据。现在,我希望该表每隔5秒自动更新一次,为此我使用了Hangfire.AspNetCore和Hangfire.MemoryStorage包。因此,我稍微修改了FetchData.razor组件,如下所示:
@page "/fetchdata"
@using WeatherTest.Data
@using Hangfire
@inject WeatherForecastService ForecastService
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from a service.</p>
@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}
@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<WeatherForecast[]> 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<WeatherForecastService>();
    services.AddHangfire(c => c.UseMemoryStorage());
    services.AddHangfireServer();
}
问题是UpdateForecasts()在OnInitializedAsync()调用时成功,但在forecasts = await ForecastService.GetForecastAsync(DateTime.Now);被Hangfire调用时失败,在forecasts = await ForecastService.GetForecastAsync(DateTime.Now);处引发以下异常:
System.NullReferenceException:‘对象引用未设置为 对象的实例。‘在我看来,由于Hangfire工作器在另一个线程中运行,因此WeatherTest.Pages.FetchData.ForecastService.get返回空。
WeatherForecastService不会被注入。我说的对吗?是否可以从多个线程使用一个单例,或者每个线程都应该有自己的服务实例?最后,我应该如何解决这个问题?
推荐答案
以下是使用标准Timer的FetchData组件。
几点:
- 我已在中添加了
Task.Delay以模拟慢速连接并显示页面正在刷新。 StateHasChanged被包装成这样await this.InvokeAsync(StateHasChanged)以确保它在UI上下文线程上运行。- 实现
IDisposable,因为我们有要断开连接的计时器事件处理程序。 
@page "/fetchdata"
@implements IDisposable
<PageTitle>Weather forecast</PageTitle>
@using StackOverflow.Server.Data
@inject WeatherForecastService ForecastService
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from a service.</p>
<div class="p-2">
    <button class="btn @this.btnCss" @onclick="ToggleTimer">@this.btnText</button>
</div>
@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}
@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作业中未注入服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
				 沃梦达教程
				
			本文标题为:Blazor服务器应用程序中的Hangfire作业中未注入服务
				
        
 
            
        
             猜你喜欢
        
	     - MoreLinq maxBy vs LINQ max + where 2022-01-01
 - C#MongoDB使用Builders查找派生对象 2022-09-04
 - Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01
 - 输入按键事件处理程序 2022-01-01
 - C# 中多线程网络服务器的模式 2022-01-01
 - WebMatrix WebSecurity PasswordSalt 2022-01-01
 - 如何用自己压缩一个 IEnumerable 2022-01-01
 - 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01
 - 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
 - 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01
 
						
						
						
						
						
				
				
				
				