提问人:Gabriel 提问时间:10/27/2023 最后编辑:maciekGabriel 更新时间:11/9/2023 访问量:120
订阅事件 c#
Subscribe to event c#
问:
我有一个正在上升事件的 EventManager 服务。 我正在尝试在 Razor 页面中订阅事件,但我无法将 OnEvent 方法绑定到该事件。我正在使用 Blazor 服务器。
这是程序中的依赖注入 .cs
builder.Services.AddTransient<IEventsManager, EventsManager>();
在这里,我有正在上升事件的服务(瞬态)
public class EventsManager:IEventsManager
{
public delegate void EventReceivedEvenHandler(EventsManager evManager, EventsView ev);
public event EventReceivedEvenHandler EventReceived;
public async Task ProcessEvents(List<Telemetry> telemetryList, string deviceProtocolId)
{
//Some code...
var eventView = new EventsView()
OnEventReceived(eventView);
}
public virtual void OnEventReceived(EventsView ev)
{
EventReceived?.Invoke(this, ev);
}
}
在这里,我有一个 Razor 页面,我在其中注入了服务:
@inject IEventsManager eventManager
protected override async Task OnInitializedAsync()
{
eventManager.EventReceived += OnEventReceived;
}
public void OnEventReceived(EventsManager evMan, EventsView ev)
{
//some code
}
程序正在运行,但公共事件 EventReceivedEvenHandler EventReceived 始终为 null。
答:
1赞
MrC aka Shaun Curtis
10/28/2023
#1
如果我没看错你的问题,你有一些后台进程捕获数据。此过程会在 中引发事件。因此,您必须注册为后台服务和 UI 的单一实例才能访问同一实例。EventsManager
IEventsMansger
由于您还在执行数据库操作,因此需要将它们与 分开。为此,可以在单独的作用域内或瞬态服务中处理数据库操作。该服务在 中注入并引发事件。IEventManager
IEventsManager
IEventsManager
下面是代码的重构版本。
各种对象。我在这里做了一些猜测。
public delegate void EventReceivedEvenHandler(EventsManager evManager, EventsView ev);
public interface IEventsManager
{
public event EventReceivedEvenHandler EventReceived;
public Task ProcessEvents(List<Telemetry> telemetryList, string deviceProtocolId);
public void OnEventReceived(EventsView ev);
}
public class EventsManager : IEventsManager
{
public event EventReceivedEvenHandler? EventReceived;
public async Task ProcessEvents(List<Telemetry> telemetryList, string deviceProtocolId)
{
//Some async code...
await Task.Yield();
var eventView = new EventsView();
OnEventReceived(eventView);
}
public virtual void OnEventReceived(EventsView ev)
{
EventReceived?.Invoke(this, ev);
}
}
public class EventsView
{
public string? Value { get; set; }
}
public class Telemetry { }
新服务:EventsHandler
namespace SO77374228.Data;
public class EventsHandler {
private IEventsManager _eventsManager;
public EventsHandler(IEventsManager eventsManager)
{
_eventsManager = eventsManager;
// get your Database stuff here
}
public async Task HandleEventAsync()
{
// Do your database saving here
// You must use the DBContextFactory with using within the method to ensure correct handling of disposal of the context
await Task.Yield();
//_eventsManager.ProcessEvents();
_eventsManager.OnEventReceived(new() { Value = $"Hello at {DateTime.Now.ToLongTimeString()} " });
}
}
服务注册:
builder.Services.AddSingleton<IEventsManager, EventsManager>();
builder.Services.AddTransient<EventsHandler>();
Index
显示数据
@page "/"
@inject IEventsManager EventsManager
@implements IDisposable
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt Title="How is Blazor working for you?" />
<div class="alert alert-primary">@_eventsView.Value</div>
@code {
private EventsView _eventsView = new();
protected override void OnInitialized()
=> this.EventsManager.EventReceived += this.OnEvent;
private void OnEvent(object sender, EventsView eventsView)
{
_eventsView = eventsView;
// as this is not a UI event we need to render the component to display any chnges
this.InvokeAsync(this.StateHasChanged);
}
// Must Dispose properly
public void Dispose()
=> this.EventsManager.EventReceived -= this.OnEvent;
}
并引发事件。Counter
@page "/counter"
@inject EventsHandler EventsHandler
<PageTitle>Counter</PageTitle>
<button class="btn btn-primary" @onclick="IncrementCount">Raise an Event</button>
@code {
private async Task IncrementCount()
{
await this.EventsHandler.HandleEventAsync();
}
}
这是一张图片,显示了两个浏览器窗口打开。单击该按钮,该事件将显示在另一个按钮中。
评论
0赞
Gabriel
10/29/2023
谢谢你的帮助。事实上,EventManager 的作用域是有限制的,我使用一个实例来接收消息,而用户正在订阅 EventManager 的其他实例。我已经纠正了这一点,新的工作正常。
评论
-=