You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从.NET Framework C# Windows应用触发.NET Core Blazor网页调用LoadData方法

实现Windows应用变更时自动更新Blazor页面数据的方案

下面提供几种实用的实现方式,可根据你的场景需求选择:

方案一:使用SignalR实现实时通知(推荐)

这是适配实时场景的最优方案,SignalR会自动处理连接管理、断线重连等底层细节,无需手动维护复杂的通信逻辑。

步骤1:在Blazor项目中配置SignalR

  1. 安装NuGet包:Microsoft.AspNetCore.SignalR
  2. 创建SignalR Hub类,定义通知客户端的方法:
using Microsoft.AspNetCore.SignalR;

public class DataUpdateHub : Hub
{
    // 触发所有连接客户端的更新事件
    public async Task NotifyDataChanged()
    {
        await Clients.All.SendAsync("OnDataChanged");
    }
}
  1. 在Program.cs中注册SignalR服务并配置跨域与端点:
var builder = WebApplication.CreateBuilder(args);

// 注册SignalR服务
builder.Services.AddSignalR();

// 配置CORS,允许Windows应用跨域访问
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowWindowsApp", policy =>
    {
        policy.WithOrigins("http://localhost:你的Windows应用端口") // 替换为实际地址
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials();
    });
});

var app = builder.Build();

app.UseCors("AllowWindowsApp");

// 映射SignalR Hub的访问端点
app.MapHub<DataUpdateHub>("/dataUpdateHub");

// 其他中间件配置(如路由、静态文件等)
app.Run();
  1. 在Blazor页面中监听SignalR通知,触发数据更新:
@page "/your-target-page"
@inject HubConnectionBuilder HubConnectionBuilder
@implements IAsyncDisposable

private HubConnection? _hubConnection;

protected override async Task OnInitializedAsync()
{
    _hubConnection = HubConnectionBuilder.WithUrl("http://localhost:Blazor项目端口/dataUpdateHub")
                                         .Build();

    // 监听服务器发来的变更通知
    _hubConnection.On("OnDataChanged", async () =>
    {
        await LoadData();
        StateHasChanged(); // 通知页面刷新
    });

    try
    {
        await _hubConnection.StartAsync();
    }
    catch (Exception ex)
    {
        Console.WriteLine($"SignalR连接失败:{ex.Message}");
    }
}

private async Task LoadData()
{
    // 你的页面数据加载逻辑
}

public async ValueTask DisposeAsync()
{
    if (_hubConnection != null)
    {
        await _hubConnection.DisposeAsync();
    }
}

步骤2:在Windows应用中发送SignalR通知

  1. 安装NuGet包:Microsoft.AspNetCore.SignalR.Client
  2. 在Windows应用的变更逻辑(如数据保存、修改完成后)中添加通知代码:
using Microsoft.AspNetCore.SignalR.Client;

// 建议全局单例维护连接,避免重复创建
var hubConnection = new HubConnectionBuilder()
    .WithUrl("http://localhost:Blazor项目端口/dataUpdateHub")
    .Build();

try
{
    await hubConnection.StartAsync();
}
catch (Exception ex)
{
    Console.WriteLine($"连接SignalR服务失败:{ex.Message}");
}

// 当数据发生变更时,调用Hub方法通知所有客户端
await hubConnection.InvokeAsync("NotifyDataChanged");

// 应用退出时关闭连接
await hubConnection.DisposeAsync();

方案二:REST API + 客户端轮询(简单场景)

如果不需要强实时性(比如允许几秒延迟),这个方案实现成本更低,无需维护长连接。

步骤1:Blazor项目添加变更标记API

创建API控制器,用于记录数据变更状态:

[ApiController]
[Route("api/[controller]")]
public class DataChangeController : ControllerBase
{
    // 用静态变量记录最后一次变更时间(生产环境可改用数据库或缓存)
    private static DateTime _lastChangeTime = DateTime.Now;

    // 供Windows应用调用,更新变更时间戳
    [HttpPost("mark-changed")]
    public IActionResult MarkChanged()
    {
        _lastChangeTime = DateTime.Now;
        return Ok();
    }

    // 供Blazor页面查询是否有新变更
    [HttpGet("has-changed")]
    public IActionResult HasChanged([FromQuery] DateTime lastCheckTime)
    {
        return Ok(_lastChangeTime > lastCheckTime);
    }
}

步骤2:Windows应用触发变更标记

当Windows应用数据发生变更时,调用API更新标记:

using System.Net.Http;

var httpClient = new HttpClient();
await httpClient.PostAsync("http://localhost:Blazor项目端口/api/datachange/mark-changed", null);

步骤3:Blazor页面轮询检查变更

在Blazor页面中定时查询API,发现变更则更新数据:

@page "/your-target-page"
@inject HttpClient HttpClient
@implements IAsyncDisposable

private PeriodicTimer? _checkTimer;
private DateTime _lastCheckTime = DateTime.Now;

protected override async Task OnInitializedAsync()
{
    // 每5秒检查一次(可根据需求调整间隔)
    _checkTimer = new PeriodicTimer(TimeSpan.FromSeconds(5));
    _ = CheckForChangesAsync();
}

private async Task CheckForChangesAsync()
{
    while (await _checkTimer.WaitForNextTickAsync())
    {
        var hasChanged = await HttpClient.GetFromJsonAsync<bool>(
            $"api/datachange/has-changed?lastCheckTime={_lastCheckTime:o}"
        );

        if (hasChanged)
        {
            await LoadData();
            _lastCheckTime = DateTime.Now;
            StateHasChanged();
        }
    }
}

private async Task LoadData()
{
    // 你的页面数据加载逻辑
}

public async ValueTask DisposeAsync()
{
    _checkTimer?.Dispose();
}

方案三:自定义WebSocket通信(复杂定制场景)

如果需要完全自定义通信协议或处理逻辑,可以直接使用原生WebSocket:

步骤1:Blazor项目配置WebSocket端点

在Program.cs中添加WebSocket支持:

var app = builder.Build();

app.UseWebSockets();

// 配置WebSocket端点
app.Map("/data-ws", async context =>
{
    if (!context.WebSockets.IsWebSocketRequest)
    {
        context.Response.StatusCode = StatusCodes.Status400BadRequest;
        return;
    }

    using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
    var buffer = new byte[1024 * 4];

    // 维护客户端连接列表(生产环境需考虑线程安全)
    // 此处简化处理,可根据需求扩展为广播逻辑
    while (webSocket.State == WebSocketState.Open)
    {
        var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
        // 收到消息后可转发给其他客户端,或直接在Blazor页面监听
    }
});

// 其他中间件配置
app.Run();

步骤2:Windows应用作为WebSocket客户端发送消息

using System.Net.WebSockets;
using System.Text;

var clientSocket = new ClientWebSocket();
await clientSocket.ConnectAsync(new Uri("ws://localhost:Blazor项目端口/data-ws"), CancellationToken.None);

// 发送变更通知消息
var messageBytes = Encoding.UTF8.GetBytes("data-updated");
await clientSocket.SendAsync(
    new ArraySegment<byte>(messageBytes),
    WebSocketMessageType.Text,
    endOfMessage: true,
    CancellationToken.None
);

// 关闭连接
await clientSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "操作完成", CancellationToken.None);

步骤3:Blazor页面监听WebSocket消息

@page "/your-target-page"
@implements IAsyncDisposable

private WebSocket? _webSocket;

protected override async Task OnInitializedAsync()
{
    _webSocket = new ClientWebSocket();
    await _webSocket.ConnectAsync(new Uri("ws://localhost:Blazor项目端口/data-ws"), CancellationToken.None);
    _ = ListenForUpdatesAsync();
}

private async Task ListenForUpdatesAsync()
{
    var buffer = new byte[1024 * 4];
    while (_webSocket.State == WebSocketState.Open)
    {
        var result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
        var message = Encoding.UTF8.GetString(buffer, 0, result.Count);
        
        if (message == "data-updated")
        {
            await LoadData();
            StateHasChanged();
        }
    }
}

private async Task LoadData()
{
    // 你的页面数据加载逻辑
}

public async ValueTask DisposeAsync()
{
    if (_webSocket != null && _webSocket.State == WebSocketState.Open)
    {
        await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "页面销毁", CancellationToken.None);
    }
}

内容的提问来源于stack exchange,提问作者MHD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 02:30:50