惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
Y
Y Combinator Blog
F
Fortinet All Blogs
H
Hackread – Cybersecurity News, Data Breaches, AI and More
N
Netflix TechBlog - Medium
T
Tailwind CSS Blog
aimingoo的专栏
aimingoo的专栏
博客园 - Franky
T
The Blog of Author Tim Ferriss
D
DataBreaches.Net
量子位
博客园 - 三生石上(FineUI控件)
I
InfoQ
Engineering at Meta
Engineering at Meta
WordPress大学
WordPress大学
阮一峰的网络日志
阮一峰的网络日志
爱范儿
爱范儿
D
Docker
美团技术团队
雷峰网
雷峰网
U
Unit 42
Stack Overflow Blog
Stack Overflow Blog
Recent Announcements
Recent Announcements
人人都是产品经理
人人都是产品经理

博客园 - Shapley

项目心得 进程间通讯方式 C#使用MCP协议调用大模型示例 SQL Server LEAD函数实践 sql server行专列一例 数据库字段排序方法两则 Sql Server生成ULID例子 审批流进化记 winform+Task+async Sql Server Begin TRY sample No service for type 'Microsoft.AspNetCore.Mvc.ViewFeatures.Filters.ValidateAntiforgeryTokenAuthorizationFilter' has been registered. 某低代码平台自定义控件技术点 Element-plus的el-date-picker控件动态切换中英文方案 Chrome浏览器无法查看页面跳转前的请求日志及解决办法 element-plus上传视频并生成缩略图(封面)方案 JWT自动刷新草案 Ajax方法POST的两种提交方式 H5项目在微信浏览器运行实录 Sql Server变量声明及使用技巧 修改Dify的Nginx对外访问端口 Task with Console(with SemaphoreSlim) Task实战 asp.net core 9.0发布centos7.9 Barrier CountdownEvent
献丑贴:Task.Run中foreach优化
Shapley · 2025-10-13 · via 博客园 - Shapley

有一个场景:

在Task.Run中循环执行N个任务,原来的写法:

var task = Task.Run(async () =>
    {
        int i = 0;
        foreach (var item in tables)
        {
            i++;
            await writefileAsync(namespace1, item, showProcess);
        }
        });
        _ = task.ContinueWith(t => { stopwatch.Stop(); MessageBox.Show($"代码生成完毕!{stopwatch.Elapsed}"); });

这种写法其实最大的问题是,既然用了taks.run,而又手动进行循环顺序处理,其实并没有发挥出task的威力来,因为task是支持多个任务并行处理的,改用并行处理:

方法一:

 var tasks = tables.Select(item => writefileAsync(namespace1, item, showProcess));

 await Task.WhenAll(tasks);
 stopwatch.Stop(); MessageBox.Show($"代码生成完毕!{stopwatch.Elapsed}");

经过对比发现,性能提升明显(单次测试处理时间:0.9s->0.4s)!

方法2:采用Parallel.ForEachAsync(最优解)

await Parallel.ForEachAsync(tables, new ParallelOptions
{
    MaxDegreeOfParallelism = 3
}, async (item, cancellationToken) =>
{
    await writefileAsync(namespace1, item, showProcess);
});
stopwatch.Stop(); MessageBox.Show($"代码生成完毕!{stopwatch.Elapsed}");

性能进一步提升!~

方法3:Parallel.ForEach

int completed = 0;
//进度条进度值 IProgress
<int> progress = new Progress<int>(value => { this.progressBar1.Value = value; });
var result = Parallel.ForEach(tables, item => { writefile(namespace1, item); // 线程安全地更新进度 int current = Interlocked.Increment(ref completed); progress.Report(current); }); if (result.IsCompleted == true) { stopwatch.Stop(); MessageBox.Show($"代码生成完毕!{stopwatch.Elapsed}"); }