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

同一机器中,Blazor WASM与Windows Worker Service如何实现数据共享存储?

同一机器下Blazor WASM与Windows Worker Service的数据共享方案

以下是几种适配你需求的实用实现方式,核心是绕过浏览器沙箱限制,建立双方可访问的共享存储或通信通道:

方案1:本地共享目录 + File System Access API(浏览器端)+ 文件监控(Worker Service)

这种方式依赖现代浏览器的文件系统访问能力,让用户指定共享目录,Worker Service监控该目录的文件变化来读取GUID。

Blazor WASM端实现步骤

  1. 引入JS互操作代码,调用浏览器API选择目录并写入文件:
// wwwroot/js/file-utils.js
async function writeGuidToFile(guid, directoryHandle) {
    const fileHandle = await directoryHandle.getFileHandle('guid-store.txt', { create: true });
    const writable = await fileHandle.createWritable();
    await writable.write(guid);
    await writable.close();
    return true;
}

async function selectDirectory() {
    return await window.showDirectoryPicker();
}
  1. 在Blazor组件中调用JS方法写入GUID:
// Pages/Index.razor
@inject IJSRuntime JS

<button @onclick="WriteGuid">写入GUID到共享目录</button>

@code {
    private async Task WriteGuid()
    {
        var directoryHandle = await JS.InvokeAsync<IJSObjectReference>("selectDirectory");
        var newGuid = Guid.NewGuid().ToString();
        await JS.InvokeAsync<bool>("writeGuidToFile", newGuid, directoryHandle);
    }
}

Windows Worker Service端实现步骤

使用FileSystemWatcher监控指定目录,读取文件内容:

// Worker.cs
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    var watcher = new FileSystemWatcher(@"C:\SharedGuidDirectory")
    {
        Filter = "guid-store.txt",
        NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName
    };

    watcher.Changed += OnFileChanged;
    watcher.Created += OnFileChanged;
    watcher.EnableRaisingEvents = true;

    while (!stoppingToken.IsCancellationRequested)
    {
        await Task.Delay(1000, stoppingToken);
    }
}

private void OnFileChanged(object sender, FileSystemEventArgs e)
{
    try
    {
        var guid = File.ReadAllText(e.FullPath);
        Console.WriteLine($"读取到新的GUID: {guid}");
    }
    catch (IOException)
    {
        Task.Delay(500).ContinueWith(_ => OnFileChanged(sender, e));
    }
}

注意事项

  • 仅支持Chrome、Edge、Firefox 118+等现代浏览器
  • 需要用户手动选择共享目录,无法静默写入本地文件

方案2:Worker Service内置本地HTTP服务(推荐)

Worker Service启动轻量级HTTP服务器,暴露API接口让Blazor WASM发送GUID,Worker Service存储并读取该数据。这种方式无需用户操作,兼容性更好。

Windows Worker Service端实现步骤

  1. 添加NuGet包:Microsoft.AspNetCore.App
  2. 配置并启动Kestrel服务器:
// Program.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.AddHostedService<Worker>();
    })
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseUrls("http://localhost:5000");
        webBuilder.Configure(app =>
        {
            app.MapPost("/api/guid", async context =>
            {
                var guid = await context.Request.ReadFromJsonAsync<string>();
                File.WriteAllText(@"C:\WorkerData\latest-guid.txt", guid);
                await context.Response.WriteAsync("GUID已存储");
            });

            app.MapGet("/api/guid", async context =>
            {
                if (File.Exists(@"C:\WorkerData\latest-guid.txt"))
                {
                    var guid = File.ReadAllText(@"C:\WorkerData\latest-guid.txt");
                    await context.Response.WriteAsync(guid);
                }
                else
                {
                    context.Response.StatusCode = StatusCodes.Status404NotFound;
                }
            });
        });
    })
    .Build();

await host.RunAsync();
  1. Worker Service中读取存储的GUID:
// Worker.cs
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    while (!stoppingToken.IsCancellationRequested)
    {
        if (File.Exists(@"C:\WorkerData\latest-guid.txt"))
        {
            var guid = File.ReadAllText(@"C:\WorkerData\latest-guid.txt");
            Console.WriteLine($"当前存储的GUID: {guid}");
        }
        await Task.Delay(5000, stoppingToken);
    }
}

Blazor WASM端实现步骤

通过HTTP请求发送GUID到本地API:

// Pages/Index.razor
@inject HttpClient Http

<button @onclick="SendGuid">发送GUID到Worker Service</button>

@code {
    private async Task SendGuid()
    {
        var newGuid = Guid.NewGuid().ToString();
        await Http.PostAsJsonAsync("http://localhost:5000/api/guid", newGuid);
        var storedGuid = await Http.GetStringAsync("http://localhost:5000/api/guid");
        Console.WriteLine(storedGuid);
    }
}

注意事项

  • 确保Worker Service以管理员权限运行(如果写入系统目录)
  • 可将存储方式替换为SQLite、本地DB等更可靠的存储方案

方案3:本地SQLite数据库

使用SQLite文件作为共享存储,Blazor WASM通过File System Access API打开SQLite文件并写入数据,Worker Service直接读取该文件。

Blazor WASM端实现

引入SQLite的WASM库(如SQLite-net-pcl),结合File System Access API操作本地SQLite文件:

// 示例代码(需引入SQLite相关包)
private async Task WriteGuidToSqlite()
{
    var directoryHandle = await JS.InvokeAsync<IJSObjectReference>("selectDirectory");
    var fileHandle = await directoryHandle.GetFileHandle("guid-db.sqlite", new { create = true });
    var db = new SQLiteAsyncConnection(fileHandle);
    await db.CreateTableAsync<GuidRecord>();
    await db.InsertAsync(new GuidRecord { Value = Guid.NewGuid().ToString() });
}

public class GuidRecord
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    public string Value { get; set; }
}

Worker Service端实现

使用Microsoft.Data.Sqlite读取SQLite文件:

private async Task ReadGuidFromSqlite()
{
    using var connection = new SqliteConnection("Data Source=C:\\SharedData\\guid-db.sqlite");
    await connection.OpenAsync();
    var command = connection.CreateCommand();
    command.CommandText = "SELECT Value FROM GuidRecord ORDER BY Id DESC LIMIT 1";
    var latestGuid = await command.ExecuteScalarAsync() as string;
    Console.WriteLine(latestGuid);
}

注意事项

  • Blazor WASM端需处理SQLite WASM的兼容性问题
  • 需确保双方操作数据库时的锁机制,避免读写冲突

内容的提问来源于stack exchange,提问作者Ali.Rashidi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 00:25:18