如何在没有阻塞调用的情况下从 IObservable 订阅中获取结果?
How to get the result from IObservable subscription without a blocking call?
我正在尝试使用 ListObjectsAsync
方法在我的 MinIO 服务器的存储桶中获取文件名。
相关代码如下:
public async Task<string> GetFileName(string userID, string datasetID)
{
ListObjectsArgs args = new ListObjectsArgs()
.WithBucket(userID)
.WithPrefix(datasetID)
.WithRecursive(true);
var files = _minio.ListObjectsAsync(args);
List<string> fileNames = new();
IDisposable subscription = files
.Subscribe(item =>
fileNames.Add(item.Key),
() => Console.WriteLine(fileNames.Count)
);
// I want to return one of the filenames here!
return "";
}
上面的代码按预期填充了列表 fileNames
,并在相应位置打印出正确数量的文件。但是,我想在上面的函数中使用数据。
我知道我可以做到以下几点:
files.ToList().Wait();
但是,这是一个阻塞调用。我应该简单地将此调用包装到 Task
中还是有其他(更好的)方法来获取所需的数据?
而不是订阅,return files.ToTask()
。
编辑
正如您在评论中提到的,首先使用 .ToList()
以便将所有接下来的事件聚集到一个事件中。如果你正在寻找一个特定的文件,就像另一个答案暗示的那样,那么使用 .Filter
.
此外,我认为您的 return 类型应该是一个包含字符串数组而不是单个字符串的任务...(除非您只想要一个文件并过滤掉所有其他文件。)
我觉得你可以一个一个地检查你收到的文件,当当前文件满足特定条件时停止处理其余的文件。喜欢:
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
Item file = null;
files.Subscribe(
item => {
if (item.Key=="MyFile")
{
file=item;
source.Cancel();
}
},
() => Console.WriteLine(fileNames.Count),
token );
我正在尝试使用 ListObjectsAsync
方法在我的 MinIO 服务器的存储桶中获取文件名。
相关代码如下:
public async Task<string> GetFileName(string userID, string datasetID)
{
ListObjectsArgs args = new ListObjectsArgs()
.WithBucket(userID)
.WithPrefix(datasetID)
.WithRecursive(true);
var files = _minio.ListObjectsAsync(args);
List<string> fileNames = new();
IDisposable subscription = files
.Subscribe(item =>
fileNames.Add(item.Key),
() => Console.WriteLine(fileNames.Count)
);
// I want to return one of the filenames here!
return "";
}
上面的代码按预期填充了列表 fileNames
,并在相应位置打印出正确数量的文件。但是,我想在上面的函数中使用数据。
我知道我可以做到以下几点:
files.ToList().Wait();
但是,这是一个阻塞调用。我应该简单地将此调用包装到 Task
中还是有其他(更好的)方法来获取所需的数据?
而不是订阅,return files.ToTask()
。
编辑
正如您在评论中提到的,首先使用 .ToList()
以便将所有接下来的事件聚集到一个事件中。如果你正在寻找一个特定的文件,就像另一个答案暗示的那样,那么使用 .Filter
.
此外,我认为您的 return 类型应该是一个包含字符串数组而不是单个字符串的任务...(除非您只想要一个文件并过滤掉所有其他文件。)
我觉得你可以一个一个地检查你收到的文件,当当前文件满足特定条件时停止处理其余的文件。喜欢:
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
Item file = null;
files.Subscribe(
item => {
if (item.Key=="MyFile")
{
file=item;
source.Cancel();
}
},
() => Console.WriteLine(fileNames.Count),
token );