📅  最后修改于: 2023-12-03 15:07:20.430000             🧑  作者: Mango
协程是一种可以暂停执行,稍后再继续执行的过程,并且在暂停时可以保留上下文的机制。在C#中,协程被称为迭代器(Iterator)。通过使用迭代器,我们可以写出更加简洁、清晰的异步代码,并且使代码具有更好的可读性。
在C#中,迭代器是一种特殊的方法,可以用yield关键字返回一个序列中的元素,而不需要将整个序列都计算出来。迭代器方法定义了一个返回IEnumerable或IEnumerable
下面是一个简单的示例,演示了如何使用迭代器来遍历一个整数数组:
public static IEnumerable<int> GetNumbers()
{
int[] numbers = new int[] { 1, 2, 3, 4, 5 };
foreach (int number in numbers)
{
yield return number;
}
}
在使用迭代器时,我们可以使用foreach语句来遍历序列中的元素。在迭代器中,每次调用yield return会返回序列中下一个元素,并在此处暂停执行,直到下一次迭代开始。
下面是一个演示迭代器使用的示例,它将异步读取文件的逻辑以同步的方式展示,但实际上仍然是异步执行的:
public static IEnumerable<string> ReadLines(string path)
{
using (StreamReader reader = new StreamReader(path))
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
在上面的代码中,ReadLines方法并不会立即读取整个文件,而是等到foreach语句第一次运行时才会读取第一行。然后,每当调用yield return时,它会暂停执行,直到下一次迭代开始。
除了基础用法之外,我们还可以使用迭代器来实现复杂的异步操作。下面是一个示例,演示了如何使用迭代器来实现异步等待:
public static IEnumerable<Task> WaitAllAsync(IEnumerable<Task> tasks)
{
List<Task> taskList = new List<Task>(tasks);
while (taskList.Count > 0)
{
int index = Task.WaitAny(taskList.ToArray());
Task completedTask = taskList[index];
taskList.RemoveAt(index);
yield return completedTask;
}
}
在上面的代码中,使用Task.WaitAny方法来等待所有的任务。每当有一个任务完成时,我们就会通过yield return返回这个已经完成的任务。通过在等待时停止执行并保留上下文,我们可以使代码看起来更加简洁和清晰。
通过使用迭代器,我们可以将异步操作包装成一种更加可读和易于理解的方式,并且简化了代码的复杂性。C#中的迭代器提供了一种优雅的方式来处理协作异步任务。