当前位置: 首页 > news >正文

c#Blazor WebAssembly在网页中多线程计算1000万次求余

在 Blazor WebAssembly 中实现多线程计算并获取线程 ID 是可行的,但需要正确配置多线程环境并处理线程安全和 UI 更新逻辑。以下是完整示例和检测方法:

一、准备工作:启用多线程支持

首先需确保项目已启用 WebAssembly 多线程,修改项目文件(.csproj):xml

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly"><PropertyGroup><TargetFramework>net8.0</TargetFramework><Nullable>enable</Nullable><ImplicitUsings>enable</ImplicitUsings><!-- 启用多线程 --><WASMEnableThreads>true</WASMEnableThreads></PropertyGroup><ItemGroup><PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0" /><PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0" PrivateAssets="all" /></ItemGroup>
</Project>

同时,服务器需配置跨域隔离头部(确保 SharedArrayBuffer 可用)。如果使用 dotnet run 调试,需在 Properties/launchSettings.json 中添加:

"profiles": {"http": {"environmentVariables": {"ASPNETCORE_ENVIRONMENT": "Development","ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.WebAssembly.Server"},"applicationUrl": "http://localhost:5000"},"https": {"environmentVariables": {"ASPNETCORE_ENVIRONMENT": "Development","ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.WebAssembly.Server"},"applicationUrl": "https://localhost:5001;http://localhost:5000"}
}

跨域隔离头部会由 Blazor 开发服务器自动添加,生产环境需在服务器(如 Nginx/Apache)配置 Cross-Origin-Opener-Policy: same-origin 和 Cross-Origin-Embedder-Policy: require-corp

二、完整代码实现:多线程计算示例

修改 Counter.razor,添加多线程计算逻辑:razor

@page "/counter"
@using System.Threading
@using System.Collections.Concurrent
@inject IJSRuntime JSRuntime<PageTitle>Counter</PageTitle><h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button><hr /><!-- 多线程测试区域 -->
<h3>多线程计算测试</h3>
<button class="btn btn-success" @onclick="StartMultiThreadCalculation">开始多线程计算</button>
@if (results.Any())
{<div class="mt-3">@foreach (var result in results){<p>线程 ID: @result.ThreadId | 耗时: @result.ElapsedMs ms | 7的倍数个数: @result.Count</p>}</div>
}@code {private int currentCount = 0;private List<ThreadResult> results = new();// 线程安全的结果队列(子线程写入,主线程读取)private ConcurrentQueue<ThreadResult> resultQueue = new();private void IncrementCount(){currentCount++;}// 线程计算结果模型private class ThreadResult{public int ThreadId { get; set; }public long ElapsedMs { get; set; }public int Count { get; set; }}// 启动3个线程private void StartMultiThreadCalculation(){results.Clear();resultQueue.Clear();// 线程1:计算 0 ~ 999万var thread1 = new Thread(CalculateMod7) { IsBackground = true };thread1.Start(0);// 线程2:计算 1000万 ~ 1999万var thread2 = new Thread(CalculateMod7) { IsBackground = true };thread2.Start(10_000_000);// 线程3:计算 2000万 ~ 2999万var thread3 = new Thread(CalculateMod7) { IsBackground = true };thread3.Start(20_000_000);// 启动定时器,定期检查结果队列并更新UI(子线程不能直接更新UI)var timer = new Timer(_ =>{// 切换到UI线程更新InvokeAsync(() =>{while (resultQueue.TryDequeue(out var result)){results.Add(result);}StateHasChanged(); // 强制刷新UI});}, null, 0, 100); // 每100ms检查一次}// 线程执行的计算逻辑:统计1000万个数中i mod 7 == 0的数量private void CalculateMod7(object? startObj){if (startObj is not int start) return;int end = start + 10_000_000; // 每个线程计算1000万次int count = 0;// 获取当前线程ID(托管线程ID)int threadId = Thread.CurrentThread.ManagedThreadId;var stopwatch = System.Diagnostics.Stopwatch.StartNew();// 执行计算for (int i = start; i < end; i++){if (i % 7 == 0){count++;}}stopwatch.Stop();// 将结果存入线程安全队列resultQueue.Enqueue(new ThreadResult{ThreadId = threadId,ElapsedMs = stopwatch.ElapsedMilliseconds,Count = count});}
}

三、关键实现说明

  1. 多线程创建
    使用 System.Threading.Thread 创建 3 个线程,分别处理不同起始范围的计算(0~1000 万、1000 万~2000 万、2000 万~3000 万)。

  2. 线程 ID 获取
    通过 Thread.CurrentThread.ManagedThreadId 获取托管线程 ID(Blazor WASM 中支持,可区分不同线程)。

  3. 线程安全与 UI 更新

    • 子线程不能直接更新 UI,需通过 ConcurrentQueue 存储结果(线程安全队列)。
    • 使用 Timer 定期检查队列,通过 InvokeAsync 切换到 UI 线程更新结果列表。
  4. 计算逻辑
    每个线程循环 1000 万次,统计能被 7 整除的数字个数,记录耗时和线程 ID。

四、检测方法:验证多线程执行

  1. 观察线程 ID
    运行后点击 “开始多线程计算”,会显示 3 个不同的 ThreadId(如 3、4、5),说明确实启用了多线程。

  2. 监控 CPU 使用率
    打开任务管理器(Windows)或活动监视器(Mac),计算过程中浏览器进程的 CPU 使用率会明显上升,说明多线程并行执行。

  3. 网络请求检测
    打开浏览器开发者工具(F12)的 Network 面板,整个计算过程中无任何 HTTP 请求,证明逻辑由本地 WASM 线程处理,而非服务器回调。

  4. 调试线程执行
    在 CalculateMod7 方法中设置断点(需在浏览器开发者工具的 Sources 面板中找到对应代码),调试时可看到断点在不同线程中触发。

五、运行结果示例

点击 “开始多线程计算” 后,会显示类似结果:plaintext

线程 ID: 3 | 耗时: 235 ms | 7的倍数个数: 1428572
线程 ID: 4 | 耗时: 241 ms | 7的倍数个数: 1428571
线程 ID: 5 | 耗时: 239 ms | 7的倍数个数: 1428571
  • 不同的 ThreadId 证明多线程生效。
  • 耗时相近说明线程并行执行(总耗时约等于单线程耗时,而非 3 倍)。

总结

Blazor WebAssembly 中的多线程计算完全在客户端通过 WASM 执行,无 HTTP 回调。通过 Thread 类创建线程,ManagedThreadId 获取线程 ID,配合线程安全队列和 UI 线程切换,可实现多线程任务并正确显示结果。网络监控和线程 ID 验证可证明逻辑在本地 WASM 中执行。

http://www.dtcms.com/a/334620.html

相关文章:

  • aws(学习笔记第五十一课) ECS集中练习(3)
  • 基于W55MH32Q-EVB 实现 HTTP 服务器配置 OLED 滚动显示信息
  • qsort实现数据排序
  • cuda编程笔记(15)--使用 CUB 和 atomicAdd 实现 histogram
  • PMP-项目管理-十大知识领域:进度管理-制定时间表、优化活动顺序、控制进度
  • 进程替换:从 “改头换面” 到程序加载的底层逻辑
  • 【深度学习计算性能】05:多GPU训练
  • TypeScript快速入门
  • MCP 大模型的扩展坞
  • 洛谷P1595讲解(加强版)+错排讲解
  • php版的FormCreate使用注意事项
  • 基于单片机的防酒驾系统设计
  • NY243NY253美光固态闪存NY257NY260
  • 24. async await 原理是什么,会编译成什么
  • 惠普声卡驱动win10装机完成检测不到声卡
  • Three.js 材质系统深度解析
  • 云原生俱乐部-RH124知识点总结(1)
  • 【CV 目标检测】Fast RCNN模型①——与R-CNN区别
  • 解锁 AI 音乐魔法,三款音乐生成工具
  • 《P4180 [BJWC2010] 严格次小生成树》
  • 服务器配置开机自启动服务
  • 基于深度强化学习的多用途无人机路径优化研究
  • 软件需求管理过程详解
  • 缓存一致性协议(Cache Coherence Protocols)与 目录协议(Directory Protocols)简介
  • 二进制为什么使用记事本读取会出乱码
  • PHP域名授权系统网站源码_授权管理工单系统_精美UI_附教程
  • RK3568 NPU RKNN(一):概念理清
  • 从通用到专业:大模型训练的两条路与遗忘难题
  • 【原理】C# 字段、属性对比及其底层实现
  • 手机版碰一碰发视频系统批量剪辑功能开发,支持OEM贴牌