☰
C#基础:通过多线程技术(Task)为多个耗时方法改造优化,提升性能
2026/11/3 17:05:12 网站建设 项目流程

一、异步方法

1.基础代码

namespace Demo { class Program { static async Task Main() { // 单线程(耗时是分方法的耗时之和) var stop = new Stopwatch(); stop.Start(); var res1 = await GetDataAsync1(); var res2 = await GetDataAsync2(); var res3 = await GetDataAsync3(); stop.Stop(); Console.WriteLine($"单线程:{res1},{res2},{res3}({stop.Elapsed.TotalSeconds})"); //多线程(耗时是分方法的最大耗时值) var stop2 = new Stopwatch(); stop2.Start(); var mut1 = GetDataAsync1(); var mut2 = GetDataAsync2(); var mut3 = GetDataAsync3(); await Task.WhenAll(mut1, mut2, mut3); stop2.Stop(); Console.WriteLine($"多线程:{await mut1},{await mut2},{await mut3}({stop2.Elapsed.TotalSeconds})"); } private static async Task<string> GetDataAsync1() { await Task.Delay(1000); return nameof(GetDataAsync1); } private static async Task<string> GetDataAsync2() { await Task.Delay(500); return nameof(GetDataAsync2); } private static async Task<string> GetDataAsync3() { await Task.Delay(2000); return nameof(GetDataAsync3); } } }

【推荐写法】

List<Task<T>> tasks = new List<Task<T>>();//装任务的列表,其中T是方法返回值的类型 foreach (var item in allTrainList) { tasks.Add(GetInfo());//GetInfo是需要提速的方法,它返回值类型是T } var results = (await Task.WhenAll(tasks)).ToList();//批量获取返回结果

2.改造步骤

1.异步方法去掉await,直接调用异步方法获取 Task
2.使用await Task.WhenAll(...)等待方法都执行完毕
3.使用变量时再用await获取(例如await mut1)

3.原理

利用多核CPU,并行处理任务,减少总执行时间。

4.优缺点

优点:提速;缺点:需要消耗CPU使用率;本质是空间换时间。

二、同步方法

1.基础代码

namespace Demo { class Program { static async Task Main() { // 单线程(耗时是分方法的耗时之和) var stop = new Stopwatch(); stop.Start(); var res1 = GetData1(); var res2 = GetData2(); var res3 = GetData3(); stop.Stop(); Console.WriteLine($"单线程:{res1},{res2},{res3}({stop.Elapsed.TotalSeconds})"); //多线程(耗时是分方法的最大耗时值) var stop2 = new Stopwatch(); stop2.Start(); var mut1 = Task.Run(() => GetData1()); var mut2 = Task.Run(() => GetData2()); var mut3 = Task.Run(() => GetData3()); await Task.WhenAll(mut1, mut2, mut3); stop2.Stop(); Console.WriteLine($"多线程:{await mut1},{await mut2},{await mut3}({stop2.Elapsed.TotalSeconds})"); } private static string GetData1() { Thread.Sleep(1000); return nameof(GetData1); } private static string GetData2() { Thread.Sleep(500); return nameof(GetData2); } private static string GetData3() { Thread.Sleep(2000); return nameof(GetData3); } } }

2.改造步骤

1.用Task.Run(...)包裹方法
2.使用await Task.WhenAll(...)等待方法都执行完毕
3.使用变量时再用await获取(例如await mut1)

3.原理及优缺点

同异步方法

三、常见问题

1.明明已开多线程,为何还是很慢

  • 某个线程耗时很长,例如10min,其余线程都耗时100ms,自然耗时很久,就为10min
  • 线程任务可能具备锁机制,不允许多线程并发访问(例如数据库限制、代码限制)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询