我有一个源元素列表Foo
,以及一个异步方法GetBoosAsync()
,可以将它们转换为Boo
类型的元素:
public class Foo
{
public string Value { get; set; }
}
public class Boo
{
public string Value { get; set; }
}
static void Main(string[] args)
{
IReadOnlyCollection<Foo> foos = GetFoos();
Task<IReadOnlyCollection<Boo>> boosTask = GetBoosAsync(foos);
boosTask.Wait();
foreach (Boo boo in boosTask.Result)
{
Console.WriteLine(boo.Value);
}
Console.ReadKey();
}
public static IReadOnlyCollection<Foo> GetFoos()
{
return Enumerable.Range(1, 100).Select(i => new Foo
{
Value = i.ToString(CultureInfo.CurrentCulture)
}).ToList();
}
public static async Task<IReadOnlyCollection<Boo>> GetBoosAsync(IReadOnlyCollection<Foo> foos)
{
List<Task<Boo>> booTasks = foos.Select(ConvertFooToBooAsync).ToList();
// Waiting for ALL conversions of Foos to Boos
await Task.WhenAll(booTasks.ToArray<Task>());
return booTasks.Select(booTask => booTask.Result).ToList();
}
public static Task<Boo> ConvertFooToBooAsync(Foo foo)
{
return Task.Factory.StartNew(() =>
{
Thread.Sleep(100);
return new Boo { Value = foo.Value };
});
}
方法GetBoosAsync()
为每个元素调用ConvertFoosToBoosAsync
,等待所有转换完成,然后返回结果列表。
问题:
如何实现方法GetBoosAsync
来返回IObservable<Boo>
,并在处理时异步返回各个元素?
即
public static IObservable<Boo> OGetBoos(IReadOnlyCollection<Foo> foos)
{
...
}
并像这样使用它:
static void Main(string[] args)
{
IReadOnlyCollection<Foo> foos = GetFoos();
IObservable<Boo> boos = OGetBoos(foos);
boos = boos.Do(boo =>
{
Console.WriteLine(boo.Value);
});
boos.Wait();
Console.ReadKey();
}
答案 0 :(得分:4)
这对你有用吗?
public static IObservable<Boo> OGetBoos(IReadOnlyCollection<Foo> foos)
{
var query =
from f in foos.ToObservable()
from b in ConvertFooToBooAsync(f).ToObservable()
select b;
return query;
}
顺便说一句,感谢您在问题中轻松编译工作代码!
答案 1 :(得分:2)
您也可以尝试这种方法。
public static IObservable<Boo> GetBoosAsync(IEnumerable<Foo> foos)
{
return foos.Select(t => Observable.FromAsync(() => ConvertFooToBooAsync(t))).Merge();
}