program.cs
builder.Services.AddScoped<ServiceInfoReceiveHandler>();
message_broker.cs
public MessageBroker(ServiceInfoReceiveHandler serviceInfoReceiveHandler)
{
_handlers = new Dictionary<string, IReceiveHandler>
{
{ "SVCMGMT/INSTALL/SVCINFO", serviceInfoReceiveHandler },
};
ReceiveMessage();
}
private void ReceiveMessage()
{
try
{
if (_handlers.ContainsKey(contentType))
{
_handlers[contentType].Receive(ea);
}
else
{
throw new Exception($"No handler for content type '{contentType}'");
}
}
}
receive.cs
if (contentType == "")
{
InstallServiceInfoReceived?.Invoke(this, (contentType, serverName, message));
}
ServiceInfoReceiveHandler.cs
public class ServiceInfoReceiveHandler : IReceiveHandler
{
public event EventHandler<(string contentType, string serverName, string message)> InstallServiceInfoReceived;
public void Receive(BasicDeliverEventArgs eventArgs)
{
var body = eventArgs.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
var serverName = eventArgs.BasicProperties.AppId;
var contentType = eventArgs.BasicProperties.ContentType;
if (contentType == "SVCMGMT/INSTALL/SVCINFO")
{
InstallServiceInfoReceived?.Invoke(this, (contentType, serverName, message));
}
}
}
install.razor
@inject ServiceInfoReceiveHandler _serviceInfoReceiveHandler
protected override async Task OnInitializedAsync()
{
_serviceInfoReceiveHandler.InstallServiceInfoReceived += OnServiceInfoReceived;
}
public void Dispose()
{
_serviceInfoReceiveHandler.InstallServiceInfoReceived -= OnServiceInfoReceived;
}
private async void OnServiceInfoReceived(object sender, (string contentType, string serverName, string message) e)
{
...
}
我正在使用blazor,并希望使用像上面那样的事件处理程序。
这在大多数情况下工作得很好,但有时OnServiceInfoReceived不会被调用。
我调试了它,发现InstallServiceInfoReceived?.Invoke();
总是被调用,
但此后OnServiceInfoReceived()
有时被调用,有时不被调用。
因为它是断断续续的,不经常调用,我想知道有什么不同。
当与另一个开发人员同时测试每个程序时,似乎就会发生这种情况。
然而,我不确定这是否会有影响,因为我是在本地工作的,它们每个都作为localhost运行,即使它们共享一个消息代理和DB。
这有问题吗?
我怀疑你正在处理组件渲染的时间问题。你给我看的代码里没有任何东西能让我不这么认为。
调用StateHasChanged
不会渲染组件。它将组件的RenderFragment
放到Renderer的队列中。只有当Renderer得到线程时间运行时,这个队列才会得到服务(由Renderer和渲染的组件)。
你是如何确定它只是有时被调用的?通过查看或不查看UI更新还是通过记录?
在if
和OnServiceInfoReceived
中添加Console.Write
或Debug.Writeline
来确定是否存在这种情况。
您还需要将以下模式应用于您的事件处理程序。
private async void OnServiceInfoReceived(object sender, (string contentType, string serverName, string message) e)
{
// do your async stuff
await this.InvokeAsync(StateHasChanged);
}
ComponentBase
继承组件有一个UI事件处理程序,它调用事件方法并为您调用StateHasChanged
。它不处理事件处理程序,所以如果你需要更新UI,你需要通过调用StateHasChanged
手动触发渲染。ComponentBase
提供了InvokeAsync方法,以确保传递的方法在UI线程上下文中由调度程序运行。