Repository: dotnet/aspnetcore
File: src/Components/Server/src/Circuits/CircuitPersistenceManager.cs (C#)

Code before:
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Components.Endpoints;
using Microsoft.AspNetCore.Components.Infrastructure;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

namespace Microsoft.AspNetCore.Components.Server.Circuits;

internal partial class CircuitPersistenceManager(
    IOptions<CircuitOptions> circuitOptions,
    ServerComponentSerializer serverComponentSerializer,
    ICircuitPersistenceProvider circuitPersistenceProvider,
    IDataProtectionProvider dataProtectionProvider)
{
    public async Task PauseCircuitAsync(CircuitHost circuit, bool saveStateToClient = false, CancellationToken cancellation = default)
    {
        await circuit.Renderer.Dispatcher.InvokeAsync(async () =>
        {
            if (circuit.IsDisposed())
            {
                return;
            }

            var renderer = circuit.Renderer;
            var persistenceManager = circuit.Services.GetRequiredService<ComponentStatePersistenceManager>();
            var collector = new CircuitPersistenceManagerCollector(circuitOptions, serverComponentSerializer, circuit.Renderer);
            using var subscription = persistenceManager.State.RegisterOnPersisting(
                collector.PersistRootComponents,
                RenderMode.InteractiveServer);

            await persistenceManager.PersistStateAsync(collector, renderer);

            if (saveStateToClient)
            {
                await SaveStateToClient(circuit, collector.PersistedCircuitState, cancellation);
            }
            else
            {
                await circuitPersistenceProvider.PersistCircuitAsync(
                    circuit.CircuitId,
                    collector.PersistedCircuitState,
                    cancellation);
            }
        });
    }

    internal async Task SaveStateToClient(CircuitHost circuit, PersistedCircuitState state, CancellationToken cancellation = default)

Review comment (bug):
We shouldn't need to guard against double disposal. If we have this issue, there's a bug somewhere else

Code after:
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Components.Endpoints;
using Microsoft.AspNetCore.Components.Infrastructure;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

namespace Microsoft.AspNetCore.Components.Server.Circuits;

internal partial class CircuitPersistenceManager(
    IOptions<CircuitOptions> circuitOptions,
    ServerComponentSerializer serverComponentSerializer,
    ICircuitPersistenceProvider circuitPersistenceProvider,
    IDataProtectionProvider dataProtectionProvider)
{
    public async Task PauseCircuitAsync(CircuitHost circuit, bool saveStateToClient = false, CancellationToken cancellation = default)
    {
        await circuit.Renderer.Dispatcher.InvokeAsync(async () =>
        {
            var renderer = circuit.Renderer;
            var persistenceManager = circuit.Services.GetRequiredService<ComponentStatePersistenceManager>();
            var collector = new CircuitPersistenceManagerCollector(circuitOptions, serverComponentSerializer, circuit.Renderer);
            using var subscription = persistenceManager.State.RegisterOnPersisting(
                collector.PersistRootComponents,
                RenderMode.InteractiveServer);

            await persistenceManager.PersistStateAsync(collector, renderer);

            if (saveStateToClient)
            {
                await SaveStateToClient(circuit, collector.PersistedCircuitState, cancellation);
            }
            else
            {
                await circuitPersistenceProvider.PersistCircuitAsync(
                    circuit.CircuitId,
                    collector.PersistedCircuitState,
                    cancellation);
            }
        });
    }

    internal async Task SaveStateToClient(CircuitHost circuit, PersistedCircuitState state, CancellationToken cancellation = default)
    {
        var (rootComponents, applicationState) = await ToProtectedStateAsync(state);
        if (!await circuit.SendPersistedStateToClient(rootComponents, applicationState, cancellation))
        {
            try