献丑贴:Task.Run中foreach优化

有一个场景:

在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}");
}

 

posted @ 2025-10-13 09:04  Shapley  阅读(4)  评论(0)    收藏  举报