Invoke()在处理blazor事件时被忽略


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更新还是通过记录?

ifOnServiceInfoReceived中添加Console.WriteDebug.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线程上下文中由调度程序运行。

相关内容

  • 没有找到相关文章

最新更新