0

0

c# 如何在 Blazor WebAssembly 中进行后台和并发处理

月夜之吻

月夜之吻

发布时间:2026-03-13 09:33:12

|

509人浏览过

|

来源于php中文网

原创

Blazor WebAssembly 不支持真正后台线程,所有“后台”操作实为单线程异步调度;CPU 密集任务需分片+Task.Yield()让出控制权;Web Workers 可实现有限并发计算;HttpClient 并发需配合 CancellationToken 和 SemaphoreSlim 节流。

c# 如何在 blazor webassembly 中进行后台和并发处理

Blazor WebAssembly 不支持真正的后台线程

Blazor WebAssembly 运行在浏览器的 WebAssembly 沙箱中,没有 ThreadThreadPoolBackgroundService 的底层支持。所谓“后台处理”,实际是基于 Task 的异步协作式调度,本质仍是单线程(UI 线程)上通过 JavaScript 引擎的微任务/宏任务队列模拟并发。

常见误解是调用 Task.Run(...) 就能“扔到后台”,但在 WASM 中它只是同步执行并立即返回已完成的 Task,不会带来并行收益,反而可能掩盖阻塞问题。

  • 不要在 WASM 中使用 Thread.SleepTask.WaitTask.Result —— 会完全冻结 UI
  • Task.Run 在 WASM 中被编译为同步调用,等价于直接执行委托体
  • 需要长时间 CPU 密集型工作时,必须分片(chunking)+ await Task.Yield()await JSRuntime.InvokeVoidAsync("setTimeout", ...) 让出控制权

用 async/await + 分片处理模拟“长任务”

例如对 10 万条数据做客户端校验或格式转换:不能一次性遍历,否则 UI 卡死数秒。需拆成小批次,每批后主动让出线程,让浏览器有机会渲染和响应。

private async Task ProcessLargeDataAsync(List<string> items)
{
    const int batchSize = 100;
    for (int i = 0; i < items.Count; i += batchSize)
    {
        var batch = items.Skip(i).Take(batchSize).ToList();
        await ProcessBatchAsync(batch); // 实际处理逻辑
<pre class='brush:php;toolbar:false;'>    // 主动让出,避免连续占用主线程
    if (i % (batchSize * 10) == 0) // 每 10 批让一次
        await Task.Yield();
}

}

private async Task ProcessBatchAsync(List<string> batch) { foreach (var item in batch) { // 模拟 CPU 工作 var result = item.ToUpperInvariant(); // 更新状态(注意线程安全:只在 UI 线程更新) StatusText = $"Processed {item}"; StateHasChanged(); // 触发重渲染 } }

关键点:Task.Yield() 告诉调度器“我先歇会”,把后续代码推到下一个事件循环;不加它,即使用了 async,整个循环仍会同步跑完。

用 JS Interop 实现真正的并发(有限场景)

WebAssembly 本身不支持多线程,但现代浏览器支持 Web Workers。可通过 JS Interop 启动 Worker,在独立线程中运行纯计算逻辑,再将结果传回 Blazor 组件。

适用场景:图像处理、加密解密、大量数值计算 —— 且逻辑可完全剥离 .NET 状态(Worker 中无法访问 NavigationManagerHttpClient 等 Blazor 服务)。

TTSMaker
TTSMaker

TTSMaker是一个免费的文本转语音工具,提供语音生成服务,支持多种语言。

下载
  • Worker 文件(calculator.worker.js)必须单独部署,不能嵌入 Razor 组件
  • 从 Blazor 调用需序列化参数(仅支持 JSON 可序列化类型),不能传 StreamIDisposable
  • 错误无法直接抛到 C#,需在 JS 中捕获并转为消息发送回来

调用示例:

private async Task<int> CalculateInWorkerAsync(int a, int b)
{
    var result = await JSRuntime.InvokeAsync<int>("startCalculationWorker", a, b);
    return result;
}

对应 JS:

function startCalculationWorker(a, b) {
  return new Promise((resolve, reject) => {
    const worker = new Worker('calculator.worker.js');
    worker.postMessage({ a, b });
    worker.onmessage = e => {
      resolve(e.data.result);
      worker.terminate();
    };
    worker.onerror = e => {
      reject(e.message);
      worker.terminate();
    };
  });
}

并发请求:HttpClient 是安全的,但要注意取消和节流

Blazor WASM 中的 HttpClient 是线程安全的,可复用实例发起多个并发请求。但默认无超时、无取消、无请求限制,容易压垮浏览器或后端。

  • 始终使用 cancellationToken:组件销毁时取消未完成请求,避免内存泄漏和状态错乱
  • 避免无限制并发:用 SemaphoreSlim 控制同时最多 3–5 个请求,尤其在循环调用 API 时
  • 不要共享 HttpClientHandler 实例跨不同 HttpClient —— WASM 中每个 HttpClient 应有独立 handler

示例(带节流):

private readonly SemaphoreSlim _throttle = new(3, 3);
<p>private async Task<string> FetchWithThrottleAsync(string url)
{
await _throttle.WaitAsync();
try
{
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
return await Http.GetStringAsync(url, cts.Token);
}
finally
{
_throttle.Release();
}
}

注意:SemaphoreSlim 在 WASM 中是完全可用的,它不依赖操作系统线程,而是基于 Task 协作实现。

真正麻烦的从来不是“怎么写 async”,而是判断哪段逻辑该切片、哪段该挪进 Worker、哪段其实只需加个 cancellationToken —— 这些边界在调试时往往只暴露在低端手机或弱网环境下。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

457

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

549

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

337

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

82

2025.09.10

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1031

2023.08.02

php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

267

2025.12.04

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

765

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

377

2025.12.24

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

37

2026.03.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11.2万人学习

C 教程
C 教程

共75课时 | 5.4万人学习

C++教程
C++教程

共115课时 | 21.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号