Add a sample for circuit handler (#16702)

pull/16707/head
Pranav K 2020-01-24 12:35:07 -08:00 committed by Luke Latham
parent a22617615d
commit e2b2df189f
1 changed files with 43 additions and 10 deletions

View File

@ -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