gpt4 book ai didi

c# - IAsyncEnumerable 的早期处置需要永远进行

转载 作者:行者123 更新时间:2023-12-02 02:26:22 31 4
gpt4 key购买 nike

我正在使用 EF Core 3.1 和 Postgresql 对数据库运行一个查询,该查询有时会根据请求的参数返回较大的结果集。我使用 Async Enumerable 来流式传输结果,有时可能需要一分钟多的时间才能完成:

try
{
IAsyncEnumerable<Entity> ae = ctxt.Entity.Where(e => e.Value > 5).AsAsyncEnumerable();

await foreach(Entity e in ae.ConfigureAwait(false))
{
//Do some work on each one here that could potentially throw an exception
}
}
catch(Exception ex)
{
//This code can take over a minute after the exception is thrown to begin executing
}

然后我摆脱了 await foreach 循环,以便更好地了解发生了什么:

IAsyncEnumerable<Entity> ae = ctxt.Entity.Where(e => e.Value > 5).AsAsyncEnumerable();
var enumerator = ae.GetAsyncEnumerator();
await enumerator.MoveNextAsync();
await enumerator.DisposeAsync();
Console.WriteLline("Done Disposing");

并发现 DisposeAsync 调用是花费时间的地方。我返回到 await foreach 并能够确认在循环内使用 break 表现出相同的行为。

接下来,我尝试创建一个非 ef IAsyncEnumerable 来查看此行为是否与 Entity Framework 隔离。

private async IAsyncEnumerable<int> IntEnumerator()
{
await Task.Delay(0).ConfigureAwait(false);

for(int i = 0; i < int.MaxValue; i++)
{
yield return i;
}
}

使用此代码,Dispose 是即时的。

IAsyncEnumerable<int> ae = IntEnumerator();
var enumerator = ae.GetAsyncEnumerator();
await enumerator.MoveNextAsync();
await enumerator.DisposeAsync();
Console.WriteLline("Done Disposing");

这让我相信这个问题是 EF core 特有的,但我不确定这是否是他们实现中的错误,或者我做错了什么。有其他人见过这样的事情并找到解决方案吗?

在 EF github 页面上提出问题之前,我想先检查一下这里。

最佳答案

看起来这实际上是 postgresql 的问题。 See the issue I opened on the Npgsql github page 。据维护者称,该问题无法解决。

关于c# - IAsyncEnumerable 的早期处置需要永远进行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60420174/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com