1

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

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,但如果我打印 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 所以这是不可能的。如何从 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;
4

1 回答 1

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 方法如下所示:

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,可以在这里找到。

于 2017-10-23T03:18:55.383 回答