yield

在 C# 中,yield 關鍵字用於定義一個迭代器方法(Iterator Method), 這個方法可以產生一個可枚舉的序列。當迭代器方法被調用時, 它不會立即執行方法體中的程式碼,而是返回一個 IEnumerator 對象。 當使用者對這個 IEnumerator 對象調用 MoveNext() 方法時,才會執行迭代器方法中的程式碼,並返回序列中的下一個元素。

使用 yield 關鍵字可以讓我們更簡潔地定義一個可枚舉的序列, 而不需要手動實現 IEnumeratorIEnumerable 接口。 此外,在使用 yield 關鍵字時,我們可以使用 yield break 來提前結束序列的產生。

好的,以下是一個使用 yield 關鍵字定義可枚舉序列的簡單範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        // 創建一個可枚舉序列
        var sequence = CountTo(5);

        // 使用 foreach 迴圈枚舉序列中的元素
        foreach (var number in sequence)
        {
            Console.WriteLine(number);
        }
    }

    // 定義一個可枚舉序列,使用 yield 關鍵字
    static IEnumerable<int> CountTo(int max)
    {
        for (int i = 1; i <= max; i++)
        {
            // 使用 yield 關鍵字返回序列中的下一個元素
            yield return i;
        }
    }
}

在這個範例中,我們使用 CountTo 方法定義了一個可枚舉序列,這個序列包含了從 1 到指定的最大值的整數。 在 CountTo 方法中,我們使用 yield return 關鍵字返回序列中的下一個元素,這個方法被調用時不會立即執行, 而是返回一個 IEnumerable<int> 對象。在 Main 方法中,我們使用 foreach 迴圈來枚舉這個序列中的元素,這時才會執行 CountTo 方法中的程式碼並產生序列。

下面是一个使用 Task.Yield() 的简单示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        Console.WriteLine("Start");

        // 使用 Task.Delay 模拟一个耗时的操作
        await Task.Delay(2000);

        Console.WriteLine("Before Yield");

        // 使用 Task.Yield 让出当前线程,让其他任务先执行
        await Task.Yield();

        Console.WriteLine("After Yield");

        // 继续执行后面的代码
        Console.WriteLine("End");
    }
}

在上面的示例中,我们使用 Task.Delay 模拟了一个耗时的操作,然后使用 Task.Yield 让出当前线程,让其他任务先执行。在执行到 Task.Yield() 的时候,控制权会立即返回给调用方,然后在后续的某个时间点继续执行。这个时间点取决于线程池的调度机制,可能是在当前线程执行完毕后,也可能是在其他线程执行完毕后。

当我们运行上面的代码时,输出结果如下:

1
2
3
4
Start
Before Yield
After Yield
End

可以看到,在执行到 Task.Yield() 之前,控制台输出了 “Before Yield”,然后在执行到 Task.Yield() 之后,控制台输出了 “After Yield”,最后输出了 “End”。这表明在调用 Task.Yield() 时,当前线程让出了控制权,其他任务得以先执行,然后在后续的某个时间点继续执行。