我正在逐步将 Ix.NET 引入到遗留项目中。我有许多返回 的存储级 API Task<IEnumerable<T>>
,但我想调整它们以IAsyncEnumerable<T>
供系统其余部分使用。似乎应该有一个辅助方法(.ToAsyncEnumerable()
IEnumerable 的ala)来帮助解决这个问题,但我找不到任何东西......我是否必须实现自己的自定义枚举器?(不难,但我不想重新发明轮子)
在Reactive Extensions的System.Interactive.dll(v1.0.2521.0)中,EnumerableEx
同时具有Memoize
方法和MemoizeAll
方法.API文档对于它们都是相同的:
创建一个枚举枚举原始枚举的枚举,并缓存其结果.
但是,这些方法显然不相同.如果我使用Memoize
,我的枚举在第一次枚举它时会有值,并且第二次似乎是空的.如果我使用MemoizeAll
那么我得到了我对任何一种方法的描述所期望的行为 - 我可以根据需要多次枚举结果并且每次都得到相同的结果,但源只被枚举一次.
谁能告诉我这些方法之间的预期差异是什么?用例是Memoize
什么?这似乎是一个相当无用的方法,真正令人困惑的文档.
System.Interactive.dll包含一个For()
具有以下实现的方法:
IEnumerable<TResult> For<TSource, TResult>(
IEnumerable<TSource> source,
Func<TSource, IEnumerable<TResult>> resultSelector)
{
return source.Select<TSource, IEnumerable<TResult>>(resultSelector).Concat<TResult>();
}
Run Code Online (Sandbox Code Playgroud)
我错过了什么或这相当于现有的Enumerable.SelectMany()
减号this
?
IEnumerable<TResult> SelectMany<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, IEnumerable<TResult>> selector)
Run Code Online (Sandbox Code Playgroud) 我有一个异步方法,说:
public async Task<T> GetAsync()
{
}
Run Code Online (Sandbox Code Playgroud)
并将从以下位置调用:
public async Task<IEnumerable<T>> GetAllAsync()
{
foreach (var item in something)
{
var result = await GetAsync();
yield return result;
}
}
Run Code Online (Sandbox Code Playgroud)
上面的语法无效,但基本上我是在异步生成器之后。我知道它可以通过 Observables 处理。我对 Rx.NET 进行了实验,并且在一定程度上奏效了。但我试图避免它给代码库带来的复杂性,更重要的是,上述需求本质上仍然不是一个反应式系统(我们的仍然是基于拉取的)。例如,我只会在一段时间内收听传入的异步流,并且我必须从消费者端停止生产者(而不仅仅是取消订阅消费者)。
我可以像这样反转方法签名:
public IEnumerable<Task<T>> GetAllAsync()
Run Code Online (Sandbox Code Playgroud)
但这使得在不阻塞的情况下进行 LINQ 操作有点棘手。我希望它是非阻塞的,并且不将整个内容加载到内存中。这个库:AsyncEnumerable正是我正在寻找的,但如何用Ix.NET做到这一点?它们的用途与我相信的相同。
换句话说,我如何利用 Ix.NETIAsyncEnumerable
在处理await
? 喜欢,
public async IAsyncEnumerable GetAllAsync()
{
foreach (var item in something)
{
var result = await GetAsync();
return // what?
}
}
Run Code Online (Sandbox Code Playgroud)