我想在我的服务中引发一个事件来检查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);
//...
}
是一个完全有效的处理程序。它将执行,但是没有任何东西等待它的完成。
您可以尝试在事件处理程序中引发异常,但是当代码在所有者的上下文中运行时,代码在事件持有人的上下文中执行。异常出现在执行上下文中,而不是父上下文中。
这并不能阻止你在其他用户的会话中弹出窗口,说事情出错了,但是实际的系统异常,没有:我知道没有办法引发它们。