我想实现一个返回一个迭代异步函数。 我们的想法是以下几点:
private async Task<IEnumerable<char>> TestAsync(string testString)
{
foreach (char c in testString.ToCharArray())
{
// do other work
yield return c;
}
}
但是,存在该函数不能是迭代器块,因为错误消息Task<IEnumerable<char>>
是不迭代器接口类型。 有没有解决的办法?
这听起来像你可能真的找的是类似IObservable<T>
这是有点像基于推送的异步IEnumerable<T>
见无功扩展,又名的Rx (Apache的2.0许可的代码)(没有隶属关系),用于与工作方法的一个巨大的主机IObservable<T>
使它象LINQ到对象和更多的工作。
这个问题IEnumerable<T>
的是,有没有真正使枚举本身异步的。 如果你不希望添加的Rx上的依赖(这实在是什么使IObservable<T>
亮),这种替代可能会为你工作:
public async Task<IEnumerable<char>> TestAsync(string testString)
{
return GetChars(testString);
}
private static IEnumerable<char> GetChars(string testString)
{
foreach (char c in testString.ToCharArray())
{
// do other work
yield return c;
}
}
但我想指出的是,不知道什么是真正被异步完成的,有可能是一个更好的方法来实现自己的目标。 你贴实际上将做任何事情异步的,我真的不知道,如果在任何代码的无// do other work
是异步的(在这种情况下,这是不是你的潜在的问题,但它会让你的代码的解决方案编译)。
为了详细说明以前的答案,你可以使用无扩展Observable.Create<TResult>
家庭的方法做你想要什么。
下面是一个例子:
var observable = Observable.Create<char>(async (observer, cancel) =>
{
for (var i = 0; !cancel.IsCancellationRequested && i < 100; i++)
{
observer.OnNext(await GetCharAsync());
}
});
这里是你如何在LINQPad使用它,例如:
// Create a disposable that keeps the query running.
// This is necessary, since the observable is 100% async.
var end = Util.KeepRunning();
observable.Subscribe(
c => Console.WriteLine(c.ToString()),
() => end.Dispose());
一个更“电池-包括”实现这种事情,包括语言支持,目前(在写作的时间)被认为包含在C#8.0。
据我所知,这是可能随时改变。