在blazor服务器端应用中触发异步事件



我想在我的服务中引发一个事件来检查blazor服务器应用程序中的某些内容。

让我们考虑这个服务,例如:

public class TestService
{
public static event AsyncEventHandler<EventArgs> OnTest;
public async Task DoSomethingAsync()
{
// DO SOMETHING
Console.WriteLine("Test");
await Task.Delay(50);
await OnTest.Invoke(this, EventArgs.Empty);
}
}
public Task AsyncEventHandler<TEventArgs>(object sender, TEventArgs e) where TEventArgs : EventArgs;

它有一个方法DoSomethingAsync调用我的AsyncEventHandler

当页面加载时,它将自己注册为这样的事件:

protected override Task OnInitializedAsync()
{
TestService.OnTest += TestService_OnTest;
return base.OnInitializedAsync();
}
private async Task TestService_OnTest(object sender, EventArgs e)
{
throw new Exception();
}
public ValueTask DisposeAsync()
{
TestService.OnTest -= TestService_OnTest;
return ValueTask.CompletedTask;
}

AsyncEventHandler允许我await.Invoke我的事件。这将导致实例化事件的用户按预期崩溃。

我想做的是:

  • User1在Page a上选择了一些元素
  • User2与User1处于同一页面,选择了一些元素,并且在User1
  • 之前按了保存键
  • 我希望User1的页面根据User2所做的选择重新验证他的选择(所以他不能选择User2已经选择的)
  • 如果代码引发任何异常,我不希望它是fire and forget for User2和User1。

我怎样才能做到这一点?

我不知道你的"AsyncEventHandler"想达到什么目的。

事件是"Fire and forget"。处理程序调用它们,然后在它们完成或屈服时继续前进。如果它们屈服,处理程序不会等待它们。

这并不意味着任何注册处理程序都不能是异步的。


private async Void OnSomethingChanged(object? sender, EnventArgs e)
{
await Task.Dalay(1000);
//...
}

是一个完全有效的处理程序。它将执行,但是没有任何东西等待它的完成。

您可以尝试在事件处理程序中引发异常,但是当代码在所有者的上下文中运行时,代码在事件持有人的上下文中执行。异常出现在执行上下文中,而不是父上下文中。

这并不能阻止你在其他用户的会话中弹出窗口,说事情出错了,但是实际的系统异常,没有:我知道没有办法引发它们。

最新更新