Skip to content

Commit e5f9307

Browse files
authored
Move Circuit Handler coverage (dotnet#17043)
1 parent cd8e974 commit e5f9307

3 files changed

Lines changed: 53 additions & 55 deletions

File tree

aspnetcore/blazor/advanced-scenarios.md

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,62 @@ description: Learn about advanced scenarios in Blazor, including how to incorpor
55
monikerRange: '>= aspnetcore-3.1'
66
ms.author: riande
77
ms.custom: mvc
8-
ms.date: 02/12/2020
8+
ms.date: 02/18/2020
99
no-loc: [Blazor, SignalR]
1010
uid: blazor/advanced-scenarios
1111
---
1212
# ASP.NET Core Blazor advanced scenarios
1313

1414
By [Luke Latham](https://github.com/guardrex) and [Daniel Roth](https://github.com/danroth27)
1515

16+
## Blazor Server circuit handler
17+
18+
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 `CircuitHandler` and registering the class in the app's service container. The following example of a circuit handler tracks open SignalR connections:
19+
20+
```csharp
21+
using System.Collections.Generic;
22+
using System.Threading;
23+
using System.Threading.Tasks;
24+
using Microsoft.AspNetCore.Components.Server.Circuits;
25+
26+
public class TrackingCircuitHandler : CircuitHandler
27+
{
28+
private HashSet<Circuit> _circuits = new HashSet<Circuit>();
29+
30+
public override Task OnConnectionUpAsync(Circuit circuit,
31+
CancellationToken cancellationToken)
32+
{
33+
_circuits.Add(circuit);
34+
35+
return Task.CompletedTask;
36+
}
37+
38+
public override Task OnConnectionDownAsync(Circuit circuit,
39+
CancellationToken cancellationToken)
40+
{
41+
_circuits.Remove(circuit);
42+
43+
return Task.CompletedTask;
44+
}
45+
46+
public int ConnectedCircuits => _circuits.Count;
47+
}
48+
```
49+
50+
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:
51+
52+
```csharp
53+
public void ConfigureServices(IServiceCollection services)
54+
{
55+
...
56+
services.AddSingleton<CircuitHandler, TrackingCircuitHandler>();
57+
}
58+
```
59+
60+
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.
61+
62+
When a circuit ends because a user has disconnected and the framework is cleaning up the circuit state, the framework disposes of the circuit's DI scope. Disposing the scope disposes any circuit-scoped DI services that implement <xref:System.IDisposable?displayProperty=fullName>. If any DI service throws an unhandled exception during disposal, the framework logs the exception.
63+
1664
## Manual RenderTreeBuilder logic
1765

1866
`Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder` provides methods for manipulating components and elements, including building components manually in C# code.

aspnetcore/blazor/handle-errors.md

Lines changed: 1 addition & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Discover how ASP.NET Core Blazor how Blazor manages unhandled excep
55
monikerRange: '>= aspnetcore-3.1'
66
ms.author: riande
77
ms.custom: mvc
8-
ms.date: 02/12/2020
8+
ms.date: 02/18/2020
99
no-loc: [Blazor, SignalR]
1010
uid: blazor/handle-errors
1111
---
@@ -95,8 +95,6 @@ Framework and app code may trigger unhandled exceptions in any of the following
9595
* [Event handlers](#event-handlers)
9696
* [Component disposal](#component-disposal)
9797
* [JavaScript interop](#javascript-interop)
98-
* [Blazor Server circuit handlers](#blazor-server-circuit-handlers)
99-
* [Blazor Server circuit disposal](#blazor-server-circuit-disposal)
10098
* [Blazor Server rerendering](#blazor-server-prerendering)
10199

102100
The preceding unhandled exceptions are described in the following sections of this article.
@@ -184,56 +182,6 @@ You have the option of using error handling code on either the .NET side or the
184182

185183
For more information, see <xref:blazor/javascript-interop>.
186184

187-
### Blazor Server circuit handlers
188-
189-
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 `CircuitHandler` and registering the class in the app's service container. The following example of a circuit handler tracks open SignalR connections:
190-
191-
```csharp
192-
using System.Collections.Generic;
193-
using System.Threading;
194-
using System.Threading.Tasks;
195-
using Microsoft.AspNetCore.Components.Server.Circuits;
196-
197-
public class TrackingCircuitHandler : CircuitHandler
198-
{
199-
private HashSet<Circuit> _circuits = new HashSet<Circuit>();
200-
201-
public override Task OnConnectionUpAsync(Circuit circuit,
202-
CancellationToken cancellationToken)
203-
{
204-
_circuits.Add(circuit);
205-
206-
return Task.CompletedTask;
207-
}
208-
209-
public override Task OnConnectionDownAsync(Circuit circuit,
210-
CancellationToken cancellationToken)
211-
{
212-
_circuits.Remove(circuit);
213-
214-
return Task.CompletedTask;
215-
}
216-
217-
public int ConnectedCircuits => _circuits.Count;
218-
}
219-
```
220-
221-
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:
222-
223-
```csharp
224-
public void ConfigureServices(IServiceCollection services)
225-
{
226-
...
227-
services.AddSingleton<CircuitHandler, TrackingCircuitHandler>();
228-
}
229-
```
230-
231-
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.
232-
233-
### Blazor Server circuit disposal
234-
235-
When a circuit ends because a user has disconnected and the framework is cleaning up the circuit state, the framework disposes of the circuit's DI scope. Disposing the scope disposes any circuit-scoped DI services that implement <xref:System.IDisposable?displayProperty=fullName>. If any DI service throws an unhandled exception during disposal, the framework logs the exception.
236-
237185
### Blazor Server prerendering
238186

239187
Blazor components can be prerendered using the `Component` Tag Helper so that their rendered HTML markup is returned as part of the user's initial HTTP request. This works by:

aspnetcore/blazor/hosting-models.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Understand Blazor WebAssembly and Blazor Server hosting models.
55
monikerRange: '>= aspnetcore-3.1'
66
ms.author: riande
77
ms.custom: mvc
8-
ms.date: 02/12/2020
8+
ms.date: 02/18/2020
99
no-loc: [Blazor, SignalR]
1010
uid: blazor/hosting-models
1111
---
@@ -115,6 +115,8 @@ Each browser screen (browser tab or iframe) that is connected to a Blazor Server
115115

116116
Blazor considers closing a browser tab or navigating to an external URL a *graceful* termination. In the event of a graceful termination, the circuit and associated resources are immediately released. A client may also disconnect non-gracefully, for instance due to a network interruption. Blazor Server stores disconnected circuits for a configurable interval to allow the client to reconnect.
117117

118+
Blazor Server allows code to define a *circuit handler*, which allows running code on changes to the state of a user's circuit. For more information, see <xref:blazor/advanced-scenarios#blazor-server-circuit-handler>.
119+
118120
### UI Latency
119121

120122
UI latency is the time it takes from an initiated action to the time the UI is updated. Smaller values for UI latency are imperative for an app to feel responsive to a user. In a Blazor Server app, each action is sent to the server, processed, and a UI diff is sent back. Consequently, UI latency is the sum of network latency and the server latency in processing the action.

0 commit comments

Comments
 (0)