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

How do I get a list of strings from an observable.Subscribe function

我得到了适用于 Minio 的 C# .net 核心 ListObjectsAsync example: ,但如何将结果捕获到列表中而不是发布到控制台?

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 returns 一个 IDisposable 所以这是不可能的。我如何从 observable 到 List ?或者如何收集数据以便将其传递到 asp.net 核心视图?

这有效 - 就像 svek 建议的那样使用 Wait。直到我读到这个才意识到语法: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;

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

The reason why you are getting 0 when you try and print names.Count is likely because you are not waiting for the asynchronous operation of the Observable <T>.Subscribe() method to complete.

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

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
)

这就是为什么这会在您使用时 return 正确计数:

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

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

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


注:
上面的代码示例来自 MSDN,可以在 here.

找到