问题标签 [iasyncenumerable]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - 我可以(或应该)使用 IAsyncEnumerable而不是任务>> 在 Web API 控制器中
我目前有一个 Web API
FromSqlRaw(...).ToListAsync()
在存储库中使用获取一行数据Ok(data.ToArray())
像Task<ActionResult<IEnumerable<MyClass>>>
通过控制器一样返回此数据。
现在我想知道是否应该或可以使用 IAsyncEnumerable 作为返回类型。这个想法是在存储库和控制器中使用它。但是,在这个(现在已经破旧的)线程中,它声明不应该使用它。这里建议的解决方案类似于:
至于控制器,我希望将响应包裹起来ActionResult
以显式设置返回码。但是,目前这似乎不起作用。
我应该将解决方案应用于存储库并将结果作为控制器中的列表使用还是保持原样?
c# - await foreach 阻止执行
我正在学习 EFCore 和IAsyncEnumerable
(现在使用 .net 5 和所有期望)并且我正在努力理解await foreach
,因为在我所做的一个测试用例中阻止了执行(或者在我看来)
问题是“之前”句子写在最后,甚至没有写在中间;并且控制台突然被完全填满了。上下文正在查询 localsql 数据库。有什么我不明白的吗?
c# - 将取消令牌传递给异步流的正确方法是什么?
一段时间以来,我一直试图了解 C# 用于异步代码的整个 async/await 模型。添加异步流(IAsyncEnumerable<T>
类型)看起来真的很酷,尤其是对于我正在编写的一些代码。
创建异步方法的最佳实践是包含一个CancellationToken
参数并将其用于取消异步进程。(理想情况下,通过将其传递给您方法中使用的底层异步方法调用。)
在创建返回异步流(an IAsyncEnumerable<T>
)的方法时,文档声明您的CancellationToken
参数应该用[EnumeratorCancellation]
属性修饰,然后使用该.WithCancellation()
方法IAsyncEnumerable<T>
本身传递的令牌。
但是,我一定是做错了什么,因为这仍然会触发警告:
CA2016:将 CancellationToken 参数转发给采用 1 的方法
无论我是否以更标准的方式执行此操作,都会出现此警告:
或者在我需要获取AsyncEnumerator
自身的地方(因为我需要一起迭代两个异步流,但不一定以相同的速率。)
我所有的异步流方法都有一个default
CancellationToken 值,这使它们成为可选参数。我认为我的问题的一部分可能是该WithCancellation()
方法适用于您已经拥有IAsyncStream<T>
但不一定将取消令牌传递给它的用例。但这并不完全有意义,感觉我要么过于频繁地传递取消令牌,要么不够(或者在我应该做另一个的时候做错了其中一个。)
在这些情况下,当我应该直接将取消令牌传递给异步流方法时,我是否只是在滥用WithCancellation()
和不必要地传递取消令牌?GetAsyncEnumerator()
基本上我不应该使用WithCancellation()
,也不应该传递任何东西,GetAsyncEnumerator()
而是应该在我的异步流方法上删除 CancellationToken 的默认值,并将令牌直接传递给它们。基本上我认为我对将 CancellationToken 传递给异步流并确定当时使用的正确方法的不同方法的数量感到困惑......
c# - 为访问者 IAsyncEnumerable 寻找更好的模式?
考虑这个片段(比原始代码简化得多):
然后,以下Parse
只是原始行为的等效行为。
但是,我确实喜欢GetSamplesAsync
代码,但编译器不喜欢:yield
不能在 lambda 中使用。
所以,我改变了函数如下,虽然它变得更不可读(而且也容易出错):
我想知道是否有更好的方法来解决这种模式。
c# - Entity Framework Core 中带有 IAsyncEnumerable 的 WHERE 子句会发生什么?
我正在将使用 Entity Framework 和 SQL Server 数据库的现有应用程序从 .NET Framework 移植到 .NET Core。在 EF6 中,您可以执行以下操作:
假设where
表达式可以在服务器端进行评估,这将转换为 SQL 查询,如SELECT columns FROM table WHERE Foo=1
.
这与 EF Core 中的方法相同。是的,我意识到我没有利用异步流,但请记住这是一个现有的应用程序,我没有时间真正重新设计它。
我遇到问题的表有数十万条记录。如果我使用 SQL Profiler,我可以看到没有WHERE
子句,因此 SQL Server 正在返回整个表,这当然不是很理想。一开始我没有注意到,因为我的单元测试是针对一个小得多的表运行的,所以没有迹象表明会有性能问题。
根据Microsoft 文档,“数据库提供程序确定可以在数据库中评估查询的哪些部分”和“查询的这些部分被翻译为特定于数据库的查询语言”。因此,当我使用简单的[column] == [value]
过滤器时,它应该可以正常工作,并且确实,同步工作完全符合预期。
我究竟做错了什么?提前致谢。
entity-framework-core - 实体框架:是否有多个 dbcontext?以及其他一些与性能相关的问题
我正在使用具有大量模型之间关系的相当复杂的模型构建日历/条目/统计应用程序。
一般来说,我关心性能,正在考虑不同的策略,并在实现应用程序之前寻找输入。
我完全是新手,DBContextPooling
所以请原谅我可能提出的愚蠢问题。但是DBContextPooling
与使用多个类有什么关系DBContext
,或者使用是否与提高性能有关,无论是单个还是多个DBContext
?
我最终可能会实施更多的DBsets
,还是应该避免它?为了简单起见,我正在考虑创建多个DBContext
类,但这会减少内存使用并提高性能吗?将应用程序拆分为更小的项目会更好/更智能吗?
IEnumerable
使用vs有任何性能差异ICollection
吗?我尽可能避免使用列表。或者使用起来会更好IAsyncEnumerable
吗?
c# - IAsyncEnumerable 和有什么区别和一个迭代器生成的 IEnumerable>?
我正在尝试找出IAsyncEnumerable<T>
带来类似IEnumerable<Task<T>>
.
我编写了以下类,它允许我等待一系列数字,每个数字之间都有定义的延迟:
这个类同时实现IAsyncEnumerable<int>
和IEnumerable<Task<int>>
。我可以同时使用它来迭代它await foreach
并foreach
获得相同的结果:
两次迭代都显示数字 0 到 4,每行之间有一秒的延迟。
唯一的优势与取消能力(即传入cancellationToken
)有关吗?还是有一些我在这里看不到的场景?
c# - 为什么我不允许在返回 IAsyncEnumerable 的方法中返回 IAsyncEnumerable
我有以下界面:
我正在尝试以这种方式实现它:
但这不会编译:
CS1622 无法从迭代器返回值。使用 yield return 语句返回一个值,或者使用 yield break 来结束迭代。
我知道我可以通过迭代可枚举来修复:
或者通过返回一个Task<IEnumerable<ValidationResult>>
:
但我想了解为什么我不能IAsyncEnumerable
在我的情况下返回一个。在编写“经典”IEnumerable
方法时,您可以 return anIEnumerable
或 yield return 多个值。为什么我不允许这样做IAsyncEnumerable
?
c# - 如何异步查询两个 IAsyncEnumerables
我有两种方法连接到两个不同的Foo
s 源,它们返回两个 s IAsyncEnumerable<Foo>
。我需要Foo
从两个来源获取所有 s 才能处理它们。
问题:我想同时(异步)查询两个源,即。不等Source1
枚举完成才开始枚举Source2
。据我了解,这就是SequentialSourcesQuery
下面的方法示例中发生的情况,对吗?
对于常规任务,我会启动第一个任务,然后是第二个任务,然后调用await Task.WhenAll
. 但是我对如何处理有点困惑IAsyncEnumerable
。
c# - 如何枚举 IAsyncEnumerable并为每个元素调用异步操作,允许每个迭代/操作对并发?
我有一个IAsyncEnumerable<string>
包含从 Web 下载的数据的流,我想将每条数据异步保存在 SQL 数据库中。所以我使用了System.Linq.Async库中的ForEachAwaitAsync
扩展方法。我的问题是下载和保存每条数据是按顺序进行的,而我希望它同时发生。
澄清一下,我不想同时下载多个数据,也不想同时保存多个数据。我想要的是,当我在数据库中保存一条数据时,下一条数据应该同时从网上下载。
以下是我当前解决方案的最小(人为)示例。下载五个项目,然后将其保存在数据库中。下载每个项目需要 1 秒,保存则需要 1 秒:
代码正在运行,但不是我想要的方式。总持续时间约为 10 秒,而不是理想的约 6 秒。
实际不受欢迎的输出:
假设的理想输出:
我正在考虑实现一个名为 的自定义扩展方法ForEachConcurrentAsync
,它与上述ForEachAwaitAsync
方法具有相同的签名,但其行为允许同时对项目进行枚举和操作。下面是这个方法的一个存根:
如何实现此功能?
其他要求:
- 在取消或失败的情况下泄漏正在运行的任务是不可接受的。当方法完成时,所有启动的任务都应该完成。
- 在枚举和动作都失败的极端情况下,应该只传播两个异常中的一个,并且任何一个都可以。
- 该方法应该是真正异步的,并且不应该阻塞当前线程(除非
action
参数包含阻塞代码,但这是调用者的责任来防止)。
说明:
如果保存数据的时间比从网上下载的时间长,该方法不应该提前下载更多的项目。最多只能预先下载一份数据,而保存前一份数据。
IAsyncEnumerable<string>
网络数据是这个问题的出发点。我不想更改IAsyncEnumerable<string>
. 我想对它的元素采取行动(通过将它们保存到数据库中),同时枚举枚举。