来自* Async方法的IObservable序列

时间:2014-05-04 21:26:15

标签: c# async-await system.reactive

我有一个源元素列表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();
}

2 个答案:

答案 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();
}