我有由 Blazor 组件和辅助角色服务组成的程序。我正在使用 .NET CORE 3.1
我的代码基于手动到 Blazor 组件
在我的工人服务方面,我有:
public event Func<double, Task> Notify;
public double Data{ get; set; }
public async Task Update(double data)
{
if (Notify != null)
{
await Notify.Invoke(data).ConfigureAwait(false);
}
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await Update(Data).ConfigureAwait(false);
...
await Task.Delay(1000, stoppingToken).ConfigureAwait(false);
}
}
在我的 Blazor 组件中:
@using MyNamespace
@inject WorkerService MyService
@implements IDisposable
<div>@DataToDisplay</div>
@code {
private double DataToDisplay{ get; set; }
protected override void OnInitialized()
{
MyService.Notify += OnNotify;
}
public async Task OnNotify(double data)
{
await InvokeAsync(() =>
{
DataToDisplay= data;
StateHasChanged();
});
}
public void Dispose()
{
MyService.Notify -= OnNotify;
}
}
调试后,我通知了 Notify 事件在 Blazor 组件中正确连接,在 OnInitialized(( 方法中(我也尝试了带有OnInitializedAsync()
的版本(,但是,每次,当服务调用Update()
方法时,在条件检查期间:if (Notify != null)
,通知为空。
我找不到原因。感谢您的任何建议!
public class InjectableService
{
public double Value { get; set; }
public event Func<Task> Notify;
public double Data { get; set; }
public async Task RefreshAsync(double value)
{
if (Notify is { })
{
Value = value;
await Notify.Invoke();
}
}
public class MyService : BackgroundService
{
private readonly InjectableService _injectableService;
public MyService(InjectableService injectableService)
{
_injectableService = injectableService;
}
public async Task Update(double value)
{
await _injectableService.RefreshAsync(value);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await Update(_injectableService.Value + 0.1).ConfigureAwait(false);
await Task.Delay(1000).ConfigureAwait(false);
}
}
}
@inject InjectableService MyService
@implements IDisposable
<p>@MyService.Value</p>
@code {
protected override void OnInitialized()
{
MyService.Notify += OnNotify;
}
public async Task OnNotify()
{
await InvokeAsync(() =>
{
StateHasChanged();
});
}
public void Dispose()
{
MyService.Notify -= OnNotify;
}
}
在启动.cs中:
services.AddHostedService<MyService>();
services.AddSingleton<InjectableService>();
基于github上的讨论:https://github.com/dotnet/extensions/issues/553 我有托管服务是暂时的,因为.NET Core 2.1。
但是,可以将其用作API,该线程底部描述的内容:
在 启动.cs, 在ConfigureServices(IServiceCollection services)
中:
services.AddSingleton<BackgroundWorkerService>();
services.AddSingleton<IHostedService>(p => p.GetService<BackgroundWorkerService>());
这显然是一种魅力。
我面临着像你这样的简单问题,因为我想通过使用事件更新 UI 中的一些元素。
查看服务注册方法,来自此处的官方Microsoft文档,services.AddSingleton<IMyDep, MyDep>();
是要走的路,因为它允许多个实现。
我所要做的就是创建一个带有接口的类:
public interface INotifierService
{
// In an Interface, its all Public!
delegate void UiChangedEventHandler(object source, EventArgs args);
event UiChangedEventHandler UiChanged; //Handler
}
以及从该接口派生的另一个类:
public class NotifierService:INotifierService
{
public event INotifierService.UiChangedEventHandler UiChanged; //Event from the base Interface
protected virtual void OnUiChanged()
{
UiChanged?.Invoke(this, EventArgs.Empty);
}
}
并在Startup.cs:
中注册它们
services.AddSingleton<Services.INotifierService, Services.NotifierService>();
而且效果很好!
当然,不要忘记将接口注入到您的 .razor 文件中并订阅其事件!