Building a Real-Time Stock Ticker in Blazor WebAssembly

February 2026

TL;DR: Blazor WebAssembly combined with SignalR creates incredibly fast, real-time dashboards entirely in C#. Use IAsyncDisposable to clean up your SignalR connections when components are destroyed to prevent memory leaks.

Building real-time dashboards used to require heavy JavaScript frameworks, complex WebSocket management, and dozens of NPM packages.

With Blazor WebAssembly and SignalR, you can build a blazing-fast real-time stock ticker using 100% C#. Let's look at how to set up the client side optimally.

1. Setting up the SignalR Hub (Backend)

First, your ASP.NET Core backend needs a Hub to broadcast the stock prices.

public class StockHub : Hub
{
    // The server will broadcast to a method called "ReceivePriceUpdate" on the client
    public async Task BroadcastPrice(string symbol, decimal price)
    {
        await Clients.All.SendAsync("ReceivePriceUpdate", symbol, price);
    }
}

2. The Blazor WebAssembly Client

The biggest mistake developers make with SignalR in Blazor is forgetting to clean up their connections. If a user navigates away from your Stock Ticker page, the connection stays open, draining battery and memory.

✅ The Good Way (Proper Component Lifecycle)

@page "/ticker"
@implements IAsyncDisposable
@inject NavigationManager Navigation

<h3>Real-Time Stock Ticker</h3>

<div class="glass-card p-4">
    @if (stockPrices.Count == 0)
    {
        <p>Waiting for market data...</p>
    }
    else
    {
        <ul>
            @foreach (var stock in stockPrices)
            {
                <li><strong>@stock.Key:</strong> $@stock.Value</li>
            }
        </ul>
    }
</div>

@code {
    private HubConnection? hubConnection;
    private Dictionary<string, decimal> stockPrices = new();

    protected override async Task OnInitializedAsync()
    {
        // 1. Build the connection
        hubConnection = new HubConnectionBuilder()
            .WithUrl(Navigation.ToAbsoluteUri("/stockhub"))
            .WithAutomaticReconnect() // Crucial for unreliable mobile networks!
            .Build();

        // 2. Listen for events
        hubConnection.On<string, decimal>("ReceivePriceUpdate", (symbol, price) =>
        {
            stockPrices[symbol] = price;
            InvokeAsync(StateHasChanged); // Tell Blazor to re-render the UI
        });

        // 3. Start the connection
        await hubConnection.StartAsync();
    }

    // 4. CLEANUP! (Prevents memory leaks)
    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}

Summary

By leveraging WithAutomaticReconnect() and properly implementing IAsyncDisposable, your Blazor SignalR applications will be robust, scalable, and memory-efficient. No JavaScript required!