枚举自动生成的 IAsyncEnumerable 是否会在等待下一个之前释放其当前项目?

问题描述 投票:0回答:1

简单的例子:

public abstract class Example {
    protected abstract Task<ReallyLargeItem> GetItem();
    
    public async IAsyncEnumerable<ReallyLargeItem> Producer() {
        while(true) {
            yield return await GetItem();
        }
    }

    public async Task Consumer()
    {
      await foreach(var item in Producer())
        Console.WriteLine(item == null ? "hello" : "world); // Just print something silly to signify the JIT cannot optimise this away here
    }
}

我们来说吧

  • 生产者在消费者开始枚举后立即发布一个非常非常大的项目。
  • 然后,接下来的一个小时没有任何反应,生产者在此期间不会再产生任何物品。

一旦 Consumer 打印了其第一行并命中循环的第二个可等待迭代,该项目是否会立即变得可释放(通过 GC)?

或者它生成的枚举器是否会保留生成的第一个项目的引用,直到生产者实际生成第二个项目 - 也就是说,至少一个小时?

我知道 SharpLab 理论上有答案,但看看生成的状态机,不幸的是我不太希望我能破译它..

c# asynchronous iasyncenumerable
1个回答
0
投票

我认为您可以通过使用

WeakReference

找到最简单的方法
WeakReference weakRef = new WeakReference(myObject);

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

if (weakRef.IsAlive) {
    Console.WriteLine("The object is still alive.");
} else {
    Console.WriteLine("The object has been garbage collected.");
}
© www.soinside.com 2019 - 2024. All rights reserved.