如何从observable.Subscribe函数中获取字符串列表

时间:2017-10-22 21:26:18

标签: c# asp.net-core minio

我为Minio工作的C#.net核心ListObjectsAsync example: ,但如何将结果捕获到List而不是发布到控制台?

using System;
using Minio.DataModel;

namespace Minio.Examples.Cases
{

    class ListObjects
    {
        // List objects matching optional prefix in a specified bucket.
        public static void Run(Minio.MinioClient minio,
                                     string bucketName = "my-bucket-name",
                                     string prefix = null,
                                     bool recursive = false)
        {
            try
            {
                Console.Out.WriteLine("Running example for API: ListObjectsAsync");
                IObservable<Item> observable = minio.ListObjectsAsync(bucketName, prefix, recursive);

                IDisposable subscription = observable.Subscribe(
                    item => Console.WriteLine("Object: {0}", item.Key),
                    ex => Console.WriteLine("OnError: {0}", ex),
                    () => Console.WriteLine("Listed all objects in bucket " + bucketName + "\n"));

                // subscription.Dispose();
            }
            catch (Exception e)
            {
                Console.WriteLine("[Bucket]  Exception: {0}", e);
            }
        }
    }
}

我尝试修改订阅功能,以便将名称添加到列表中,而不是将它们打印到控制台:

IDisposable subscription = observable.Subscribe(
item => names.Add(item.Key), 
ex => Console.WriteLine("OnError: {0}", ex), 
() => Console.WriteLine("Listed all objects in bucket "  
+ bucketName + "\n" + "count:" + names.Count +"\n"));

它打印7,但如果我在Subscribe之外打印names.Count它会打印0;

这就是我想要做的事:

List<Item> myList = new List<Item>(observable.ToList().Subscribe(x => Console.WriteLine("do something"),
  ex => Console.WriteLine("OnError: {0}", ex),
  () => Console.WriteLine("Done" + "\n"));

但是observable返回一个IDisposable,所以这是不可能的。如何从可观察到列表?或者我如何收集数据以便将其传递到asp.net核心视图?

这样做 - 使用等待就像svek建议的那样。在我读到这个之前没有意识到语法:waiting IObservable to get all elements error

List<Item> names = new List<Item>();

IDisposable subscription = observable.ToList().Subscribe(
  x => names.AddRange(x),
  ex => Console.WriteLine("OnError: {0}", ex), 
  () => Console.WriteLine("Done" + "\n") );
observable.Wait();
Console.WriteLine("out of subscribe count:" + names.Count + "\n");
subscription.Dispose();
return names;

1 个答案:

答案 0 :(得分:3)

虽然我发现你的代码比我习惯的代码更难阅读。关于您的主题,如何从observable.Subscribe函数中获取字符串列表 代码本身是有效的

  

您尝试打印0时获得names.Count的原因可能是因为您没有等待Observable <T>.Subscribe()方法的异步操作完成。

为了帮助您理解代码的语法,请参阅以下示例:

IObservable<int> source = Observable.Range(1, 10);
IDisposable subscription = source.Subscribe(
    x => Console.WriteLine("OnNext: {0}", x),
    ex => Console.WriteLine("OnError: {0}", ex.Message),
    () => Console.WriteLine("OnCompleted"));

Console.WriteLine("Press ENTER to unsubscribe...");
Console.ReadLine();
subscription.Dispose();

可以重写以使用Observer类型,如下所示:

IObservable<int> source = Observable.Range(1, 10);
IObserver<int> observer = Observer.Create<int>(
    x => Console.WriteLine("OnNext: {0}", x),
    ex => Console.WriteLine("OnError: {0}", ex.Message),
    () => Console.WriteLine("OnCompleted"));        
IDisposable subscription = source.Subscribe(observer);

Console.WriteLine("Press ENTER to unsubscribe...");
Console.ReadLine();
subscription.Dispose();

上述重构将有助于澄清解决方案。如您所见,第一个代码块中使用的参数实际上是调用Observer.Create<T>()方法。

Observer.Create Method看起来像这样:

public static IObserver<T> Create<T>(
    Action<T> onNext,
    Action<Exception> onError,
    Action onCompleted
)

这就是为什么当您使用时,这将正确返回计数:

// OnCompleted
() => Console.WriteLine("Listed all objects in bucket " 
          + bucketName + "\n" + "count:" + names.Count +"\n"));

因为在执行向控制台显示消息的操作之前,它正在等待序列完成。

要解决您的问题,您只需等待异步Subscribe操作先完成,然后再尝试枚举。

注意:
上面的代码示例来自MSDN,可以找到here