Add a sample for circuit handler (#16702)
parent
a22617615d
commit
e2b2df189f
|
@ -5,7 +5,7 @@ description: Discover how ASP.NET Core Blazor how Blazor manages unhandled excep
|
|||
monikerRange: '>= aspnetcore-3.1'
|
||||
ms.author: riande
|
||||
ms.custom: mvc
|
||||
ms.date: 12/18/2019
|
||||
ms.date: 01/22/2020
|
||||
no-loc: [Blazor, SignalR]
|
||||
uid: blazor/handle-errors
|
||||
---
|
||||
|
@ -104,7 +104,7 @@ The preceding unhandled exceptions are described in the following sections of th
|
|||
When Blazor creates an instance of a component:
|
||||
|
||||
* The component's constructor is invoked.
|
||||
* The constructors of any non-singleton DI services supplied to the component's constructor via the [`@inject`](xref:blazor/dependency-injection#request-a-service-in-a-component) directive or the [`[Inject]`](xref:blazor/dependency-injection#request-a-service-in-a-component) attribute are invoked.
|
||||
* The constructors of any non-singleton DI services supplied to the component's constructor via the [`@inject`](xref:blazor/dependency-injection#request-a-service-in-a-component) directive or the [`[Inject]`](xref:blazor/dependency-injection#request-a-service-in-a-component) attribute are invoked.
|
||||
|
||||
A circuit fails when any executed constructor or a setter for any `[Inject]` property throws an unhandled exception. The exception is fatal because the framework can't instantiate the component. If constructor logic may throw exceptions, the app should trap the exceptions using a [try-catch](/dotnet/csharp/language-reference/keywords/try-catch) statement with error handling and logging.
|
||||
|
||||
|
@ -157,7 +157,7 @@ If user code doesn't trap and handle the exception, the framework logs the excep
|
|||
|
||||
### Component disposal
|
||||
|
||||
A component may be removed from the UI, for example, because the user has navigated to another page. When a component that implements <xref:System.IDisposable?displayProperty=fullName> is removed from the UI, the framework calls the component's <xref:System.IDisposable.Dispose*> method.
|
||||
A component may be removed from the UI, for example, because the user has navigated to another page. When a component that implements <xref:System.IDisposable?displayProperty=fullName> is removed from the UI, the framework calls the component's <xref:System.IDisposable.Dispose*> method.
|
||||
|
||||
If the component's `Dispose` method throws an unhandled exception, the exception is fatal to the circuit. If disposal logic may throw exceptions, the app should trap the exceptions using a [try-catch](/dotnet/csharp/language-reference/keywords/try-catch) statement with error handling and logging.
|
||||
|
||||
|
@ -184,16 +184,49 @@ For more information, see <xref:blazor/javascript-interop>.
|
|||
|
||||
### Circuit handlers
|
||||
|
||||
Blazor allows code to define a *circuit handler*, which receives notifications when the state of a user's circuit changes. The following states are used:
|
||||
Blazor Server allows code to define a *circuit handler*, which allows running code on changes to the state of a user's circuit. A circuit handler is implemented by deriving from <xref:Microsoft.AspNetCore.Components.Servers.Circuits.CircuitHandler /> and registering the class in the app's service container. The following example of a circuit handler tracks open SignalR connections:
|
||||
|
||||
* `initialized`
|
||||
* `connected`
|
||||
* `disconnected`
|
||||
* `disposed`
|
||||
```csharp
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components.Server.Circuits;
|
||||
|
||||
Notifications are managed by registering a DI service that inherits from the `CircuitHandler` abstract base class.
|
||||
public class TrackingCircuitHandler : CircuitHandler
|
||||
{
|
||||
private HashSet<Circuit> _circuits = new HashSet<Circuit>();
|
||||
|
||||
If a custom circuit handler's methods throw an unhandled exception, the exception is fatal to the circuit. To tolerate exceptions in a handler's code or called methods, wrap the code in one or more [try-catch](/dotnet/csharp/language-reference/keywords/try-catch) statements with error handling and logging.
|
||||
public override Task OnConnectionUpAsync(Circuit circuit,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
_circuits.Add(circuit);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override Task OnConnectionDownAsync(Circuit circuit,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
_circuits.Remove(circuit);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public int ConnectedCircuits => _circuits.Count;
|
||||
}
|
||||
```
|
||||
|
||||
Circuit handlers are registered using DI. Scoped instances are created per instance of a circuit. Using the `TrackingCircuitHandler` in the preceding example, a singleton service is created because the state of all circuits must be tracked:
|
||||
|
||||
```csharp
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
...
|
||||
services.AddSingleton<CircuitHandler, TrackingCircuitHandler>();
|
||||
}
|
||||
```
|
||||
|
||||
If a custom circuit handler's methods throw an unhandled exception, the exception is fatal to the Blazor Server circuit. To tolerate exceptions in a handler's code or called methods, wrap the code in one or more [try-catch](/dotnet/csharp/language-reference/keywords/try-catch) statements with error handling and logging.
|
||||
|
||||
### Circuit disposal
|
||||
|
||||
|
|
Loading…
Reference in New Issue