
- 使用
async
和await
关键字(基于 Task - 推荐用于简单场景)
- 原理:
async
关键字用于修饰方法,表示这个方法是异步的。await
关键字用于暂停异步方法的执行,直到等待的任务完成。在 C# 中,很多异步操作都返回Task
或Task<T>
类型的对象,await
可以作用于这些对象。 - 示例代码:
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
HttpClient client = new HttpClient();
Task<string> task1 = client.GetStringAsync("https://example.com/api1");
Task<string> task2 = client.GetStringAsync("https://example.com/api2");
string result1 = await task1;
string result2 = await task2;
Console.WriteLine(result1);
Console.WriteLine(result2);
}
}
- 在上述示例中,
Main
方法被标记为async
,表示它是一个异步方法。在方法内部,通过HttpClient
发起了两个异步网络请求(GetStringAsync
方法返回Task<string>
)。然后使用await
分别等待这两个任务完成,并获取结果打印出来。这样,两个网络请求是异步执行的,而不是顺序等待一个完成再执行下一个,从而提高了效率。
- 使用
Task.Run
(用于将同步方法转换为异步任务)
- 原理:
Task.Run
方法用于在后台线程池上运行一个委托(可以是一个方法),它返回一个Task
对象。这样就可以把一个原本是同步的操作放到一个新的线程中执行,实现异步效果。 - 示例代码:
using System;
using System.Threading.Tasks;
class Program
{
static void SynchronousMethod()
{
// 模拟一个耗时的同步操作
for (int i = 0; i < 1000000; i++)
{
Console.Write(i);
}
}
static async Task Main()
{
Task task = Task.Run(() => SynchronousMethod());
// 在这里可以做其他事情,比如等待另一个任务或者执行其他非阻塞操作
await task;
}
}
- 在这个示例中,
SynchronousMethod
是一个同步方法,通过Task.Run
将其包装成一个异步任务。Main
方法可以在等待这个任务完成的同时做其他事情,提高了程序的并发性能。
- 使用
Parallel
类(用于并行执行多个任务)
- 原理:
Parallel
类提供了一种简单的方式来并行处理一组任务。它会自动利用多个处理器核心(如果可用)来加速任务的执行。Parallel
类主要使用Parallel.For
和Parallel.ForEach
方法,分别用于迭代执行一组任务和对一个集合中的每个元素执行任务。 - 示例代码:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
class Program
{
static void ProcessItem(int item)
{
// 模拟对每个元素的处理操作
Console.WriteLine($"Processing item {item}");
}
static void Main()
{
List<int> items = new List<int> { 1, 2, 3, 4, 5 };
Parallel.ForEach(items, ProcessItem);
}
}
- 在这个示例中,
Parallel.ForEach
方法会并行地对items
集合中的每个元素调用ProcessItem
方法。这样,这些任务不是顺序执行的,而是根据系统的资源情况尽可能地并行处理,提高了处理速度。不过需要注意的是,Parallel
类在处理共享资源等情况时可能会导致数据竞争等问题,需要谨慎使用。