如何正确处理 Blazor 服务器端另一个线程(来自计时器)中抛出的异常?
理想情况下,我希望错误像所有其他异常一样冒泡并触发黄色错误栏。
不幸的是,异常终止了整个应用程序。我可以在方法调用周围放置一个 try catch,但更愿意在全局范围内处理这个问题。
这是我运行的代码,在 Elapsed-Handler (HandleSearchTimerElapsed) 内抛出异常。这会终止应用程序,这显然是我不想要的。
@page "/"
<button class="btn btn-primary" @onclick="ResetDelayTimer">Throw Error with Timer</button>
<button class="btn btn-primary" @onclick="@(() => throw new Exception("Simple Error"))">Simple Error without Timer (shows yellow error bar)</button>
@code {
private int currentCount = 0;
private System.Timers.Timer? _delayTimer;
protected override void OnInitialized()
{
_delayTimer = new(200) { AutoReset = false, };
_delayTimer.Elapsed += HandleSearchTimerElapsed;
base.OnInitialized();
}
private async void HandleSearchTimerElapsed(object? sender, System.Timers.ElapsedEventArgs args)
{
try
{
await InvokeAsync(() => throw new Exception("From InvokeAsync in Timer"));
}
catch (Exception)
{
// How to throw this "normally" ? i want to see the yellow exception bar
throw; // This terminates the Application
}
}
private void ResetDelayTimer()
{
_delayTimer!.Stop();
_delayTimer.Start();
}
}
我可以从 blazor 触发“正常”异常处理程序吗?
在 async void
函数中使用 try-catch 是
重要,以确保其安全。这些函数对于从 EventHandler 或 Timer 调用异步代码至关重要。
要模拟组件引发异常并使其到达 ErrorBoundary,请使用 DispatchExceptionAsync,如下所示。
private async void HandleSearchTimerElapsed(object? sender, System.Timers.ElapsedEventArgs args)
{
try
{
await InvokeAsync(() => throw new Exception("From InvokeAsync in Timer"));
}
catch (Exception)
{
await DispatchExceptionAsync(e);
}
}
我认为它是 .NET 8.0 中的全新内容 https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.componentbase.dispatchexceptionasync?view=aspnetcore-8.0