最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - NET 8 - SignalR HubConnection - Cannot access a disposed object - Stack Overflow

programmeradmin2浏览0评论

I have an ASP.NET Core 8.0 Blazorise app. A very simple app that just brings a random number to the user.

When I run my app and enter the home page, SignalR immediately closes and I get this message:

Reconnect failed: Cannot access a disposed object. Object name: 'Microsoft.AspNetCore.SignalR.Client.HubConnection'.

when I'm trying to call

await _myHubConnection.StartAsync(); 

in the ReconnectAsync method.

Program.cs:

using App.Components;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
builder.Services.AddSignalR();

var app = builder.Build();

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseStaticFiles();
app.MapControllers();

app.MapHub<MyHub>("/myHub");

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.Run();

Hub.cs:

using Microsoft.AspNetCore.SignalR;

public class MyHub : Hub
{
    private static readonly Random _random = new Random();

    public async Task StreamData()
    {
        while (true)
        {
            var temp = _random.Next(-10, 35);  // Random data
            await Clients.All.SendAsync("ReceiveData", temp);
            await Task.Delay(1000);  // Update every 1 second
        }
    }
}

Page.cs:

@page "/"

<PageTitle>Home</PageTitle>

@inject NavigationManager Navigation
@using Microsoft.AspNetCore.SignalR.Client
@implements IAsyncDisposable


@code {
    private HubConnection? _myHubConnection;
    private int MyData = 0;

    protected override async Task OnInitializedAsync()
    {

        _myHubConnection = new HubConnectionBuilder()
        .WithUrl(Navigation.ToAbsoluteUri("/myHub"))
        .Build();

        _myHubConnection.On<int>("ReceiveData", async (data) =>
        {
            MyData = data;
            Console.WriteLine($"Received data: {data}");
            InvokeAsync(StateHasChanged);
        });

        await _myHubConnection.StartAsync();
        if (_myHubConnection != null)
        {
            await _myHubConnection.SendAsync("StreamData");
        }

        // Handle connection events
        _myHubConnection.Closed += async (exception) =>
        {
            Console.WriteLine($"Connection closed: {exception?.Message}");
            await ReconnectAsync();
        };

    }

    private async Task ReconnectAsync()
    {
        while (_myHubConnection.State.Equals(HubConnectionState.Disconnected))
        {
            try
            {
                // Check if the connection is disposed before trying to reconnect
                if (_myHubConnection != null && _myHubConnection.State == HubConnectionState.Disconnected)
                {
                    Console.WriteLine("Attempting to reconnect...");
                    await _myHubConnection.StartAsync();
                }

                Console.WriteLine("Reconnected successfully.");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Reconnect failed: {ex.Message}");
            }

            await Task.Delay(5000); // Wait before retrying
        }
    }

    public async ValueTask DisposeAsync()
    {
        Console.WriteLine("Disposing called!");

        // Dispose both hub connections
        if (_myHubConnection != null)
        {
            await _myHubConnection.DisposeAsync();
        }
    }
}


<h2 class="title">Dashboard</h2>

<div class="container">
    <div class="card">
        <h3>Data</h3>
        <p class="value">@MyData</p>
    </div>
</div>

What could be the issue?

I can provide more code / details if needed

I have an ASP.NET Core 8.0 Blazorise app. A very simple app that just brings a random number to the user.

When I run my app and enter the home page, SignalR immediately closes and I get this message:

Reconnect failed: Cannot access a disposed object. Object name: 'Microsoft.AspNetCore.SignalR.Client.HubConnection'.

when I'm trying to call

await _myHubConnection.StartAsync(); 

in the ReconnectAsync method.

Program.cs:

using App.Components;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
builder.Services.AddSignalR();

var app = builder.Build();

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseStaticFiles();
app.MapControllers();

app.MapHub<MyHub>("/myHub");

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.Run();

Hub.cs:

using Microsoft.AspNetCore.SignalR;

public class MyHub : Hub
{
    private static readonly Random _random = new Random();

    public async Task StreamData()
    {
        while (true)
        {
            var temp = _random.Next(-10, 35);  // Random data
            await Clients.All.SendAsync("ReceiveData", temp);
            await Task.Delay(1000);  // Update every 1 second
        }
    }
}

Page.cs:

@page "/"

<PageTitle>Home</PageTitle>

@inject NavigationManager Navigation
@using Microsoft.AspNetCore.SignalR.Client
@implements IAsyncDisposable


@code {
    private HubConnection? _myHubConnection;
    private int MyData = 0;

    protected override async Task OnInitializedAsync()
    {

        _myHubConnection = new HubConnectionBuilder()
        .WithUrl(Navigation.ToAbsoluteUri("/myHub"))
        .Build();

        _myHubConnection.On<int>("ReceiveData", async (data) =>
        {
            MyData = data;
            Console.WriteLine($"Received data: {data}");
            InvokeAsync(StateHasChanged);
        });

        await _myHubConnection.StartAsync();
        if (_myHubConnection != null)
        {
            await _myHubConnection.SendAsync("StreamData");
        }

        // Handle connection events
        _myHubConnection.Closed += async (exception) =>
        {
            Console.WriteLine($"Connection closed: {exception?.Message}");
            await ReconnectAsync();
        };

    }

    private async Task ReconnectAsync()
    {
        while (_myHubConnection.State.Equals(HubConnectionState.Disconnected))
        {
            try
            {
                // Check if the connection is disposed before trying to reconnect
                if (_myHubConnection != null && _myHubConnection.State == HubConnectionState.Disconnected)
                {
                    Console.WriteLine("Attempting to reconnect...");
                    await _myHubConnection.StartAsync();
                }

                Console.WriteLine("Reconnected successfully.");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Reconnect failed: {ex.Message}");
            }

            await Task.Delay(5000); // Wait before retrying
        }
    }

    public async ValueTask DisposeAsync()
    {
        Console.WriteLine("Disposing called!");

        // Dispose both hub connections
        if (_myHubConnection != null)
        {
            await _myHubConnection.DisposeAsync();
        }
    }
}


<h2 class="title">Dashboard</h2>

<div class="container">
    <div class="card">
        <h3>Data</h3>
        <p class="value">@MyData</p>
    </div>
</div>

What could be the issue?

I can provide more code / details if needed

Share Improve this question edited Mar 19 at 21:22 marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Mar 19 at 21:13 JebathonJebathon 4,61314 gold badges62 silver badges117 bronze badges 1
  • See following : stackoverflow/questions/55795669/… – jdweng Commented Mar 19 at 21:34
Add a comment  | 

1 Answer 1

Reset to default 1

You could try this code:

@page "/page1"
@inject NavigationManager Navigation
@using Microsoft.AspNetCore.SignalR.Client
@implements IAsyncDisposable


@code {
    private HubConnection? _myHubConnection;
    private int MyData = 0;

    protected override async Task OnInitializedAsync()
    {

        _myHubConnection = new HubConnectionBuilder()
        .WithUrl(Navigation.ToAbsoluteUri("/myHub"))
        .Build();

        _myHubConnection.On<int>("ReceiveData", async (data) =>
        {
            MyData = data;
            Console.WriteLine($"Received data: {data}");
            StateHasChanged();
        });

        await _myHubConnection.StartAsync();
        if (_myHubConnection != null)
        {
            await _myHubConnection.SendAsync("StreamData");
        }

        // Handle connection events
        _myHubConnection.Closed += async (exception) =>
        {
            Console.WriteLine($"Connection closed: {exception?.Message}");
            await ReconnectAsync();
        };

    }

    private async Task ReconnectAsync()
    {
        while (_myHubConnection?.State == HubConnectionState.Disconnected)
        {
            try
            {
                // Check if the connection is disposed
                if (_myHubConnection?.State == HubConnectionState.Disconnected)
                {
                    // If the connection is disposed, create a new one
                    Console.WriteLine("Recreating the connection...");
                    _myHubConnection = new HubConnectionBuilder()
                        .WithUrl(Navigation.ToAbsoluteUri("/myHub"))
                        .Build();
                    _myHubConnection.On<int>("ReceiveData", async (data) =>
                                        {
                                            MyData = data;
                                            Console.WriteLine($"Received data: {data}");
                                            StateHasChanged();
                                        });
                    await _myHubConnection.StartAsync();

                    Console.WriteLine("Reconnected successfully.");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Reconnect failed: {ex.Message}");
            }
            await Task.Delay(5000); // Wait before retrying
        }
    }


    public async ValueTask DisposeAsync()
    {
        Console.WriteLine("Disposing called!");

        // Dispose both hub connections
        if (_myHubConnection != null)
        {
            await _myHubConnection.DisposeAsync();
        }
    }
}


<h2 class="title">Dashboard</h2>

<div class="container">
    <div class="card">
        <h3>Data</h3>
        <p class="value">@MyData</p>
    </div>
</div>

You are getting this error because the connection is closed and disposed, it cannot be reused.

Result:

发布评论

评论列表(0)

  1. 暂无评论