Open njlr opened 1 year ago
Hi everyone, I would like to do the same as @njlr . I have tried also with TaskCompletionSource to get access to the stream but at that time it is already disposed. In the class "OperationHelper" I can see the method "GetObjectStreamAsync" which is used when executing the FuncCallback. However, it's using a "using" statement which will dispose the stream afterwards. Is it possible to offer a possibility to access the non-disposed stream? Thank you very much!
I can confirm that the following has worked for me, however with the huge drawback to clone the entire project into my own solution.
After having cloned the project and adjusted the namespaces to distinguish the code from the original assembly, I have simply removed the using statement in the following method of the class OperationHelper.cs:
private async Task GetObjectStreamAsync(GetObjectArgs args, ObjectStat objectStat,
Func<Stream, CancellationToken, Task> cb,
CancellationToken cancellationToken = default)
{
var requestMessageBuilder = await CreateRequest(args).ConfigureAwait(false);
var response =
await ExecuteTaskAsync(NoErrorHandlers, requestMessageBuilder, cancellationToken: cancellationToken)
.ConfigureAwait(false);
}
Here's the code to access it then, please note I am using the newer Function callback:
var tcs = new TaskCompletionSource<Stream>();
var objArgs = new MyMinio.GetObjectArgs().WithBucket(request.BucketName).WithObject(request.ObjectName)
.WithCallbackStream((stream, cancellationToken) =>
{
tcs.SetResult(stream);
return Task.CompletedTask;
});
var response = await _clientFacade.GetObjectStreamAsync(objArgs, cancellationToken);
var streamResult = await tcs.Task;
var fileStreamResult = new FileStreamResult(streamResult, "application/octet-stream")
{
FileDownloadName = fileName,
EnableRangeProcessing = false
};
Please also note that the _clientFacade is simply my own wrapper to the Minio Code. There I manage the instances of the MinioClient and the method simply calls the GetObjectAsync method from my cloned project code:
return await _myMinioClient.GetObjectAsync(args, cancellationToken).ConfigureAwait(false);
Doing so the stream won't be disposed when I forward it as a FileStreamResult to any consumer. The lifecycle of the Stream is controlled then by .NET framework itself. For all other Minio related methods (upload files, accessing buckets, etc.) I use the original Minio code from the external assembly.
I would love a function that explicitly returns a stream that the caller is expected to dispose, rather than using a TaskCompletionSource
. This is something that the AWS S3 client offers.
Would the maintainers accept a PR for this?
@njlr can you open a PR for this?
There does not appear to be an API for getting a
Stream
of an object.I came across
GetObjectArgs::WithCallbackStream
but it appears that theStream
contents are somehow tied to the lifespan of theTask
that you return.Obviously the following seems like a bad idea, although it does work!
What is the intended approach here?