Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix progress timing for PutObject_Test9 test (fixes #1078) #1079

Merged
merged 3 commits into from
May 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -1874,6 +1874,7 @@ try
var ssec = new SSEC(aesEncryption.Key);
var progress = new Progress<ProgressReport>(progressReport =>
{
// Progress events are delivered asynchronously (see remark below)
Console.WriteLine(
$"Percentage: {progressReport.Percentage}% TotalBytesTransferred: {progressReport.TotalBytesTransferred} bytes");
if (progressReport.Percentage != 100)
Expand All @@ -1895,7 +1896,14 @@ catch(MinioException e)
Console.WriteLine("Error occurred: " + e);
}
```

**Remark:**
Note that the default [Progress<T> class](https://learn.microsoft.com/en-us/dotnet/api/System.Progress-1) post progress
updates to the SynchronizationContext when the instance was constructed
([source](https://learn.microsoft.com/en-us/dotnet/api/system.progress-1#remarks)). This means that progress updates are
sent asynchronous. If you do want to receive the events synchronous, then use the `Minio.Helper.SyncProgress<T>` instead,
but make sure you understand the implications. Progress events are sent synchronous, so they may be invoked on an
arbitrary thread (mostly a problem for UI applications) and performing long-running and/or blocking operations will
degrade upload performance.

<a name="statObject"></a>
### StatObjectAsync(StatObjectArgs args)
Expand Down
3 changes: 2 additions & 1 deletion Minio.Examples/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using Minio.DataModel.Notification;
using Minio.DataModel.ObjectLock;
using Minio.Examples.Cases;
using Minio.Helper;

namespace Minio.Examples;

Expand Down Expand Up @@ -110,7 +111,7 @@ public static async Task Main()
var destBucketName = GetRandomName();
var destObjectName = GetRandomName();
var lockBucketName = GetRandomName();
var progress = new Progress<ProgressReport>(progressReport =>
var progress = new SyncProgress<ProgressReport>(progressReport =>
{
Console.WriteLine(
$"Percentage: {progressReport.Percentage}% TotalBytesTransferred: {progressReport.TotalBytesTransferred} bytes");
Expand Down
4 changes: 2 additions & 2 deletions Minio.Functional.Tests/FunctionalTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3495,7 +3495,7 @@ internal static async Task PutObject_Test9(IMinioClient minio)
const string contentType = "application/octet-stream";
var percentage = 0;
var totalBytesTransferred = 0L;
var progress = new Progress<ProgressReport>(progressReport =>
var progress = new SyncProgress<ProgressReport>(progressReport =>
{
percentage = progressReport.Percentage;
totalBytesTransferred = progressReport.TotalBytesTransferred;
Expand Down Expand Up @@ -3552,7 +3552,7 @@ internal static async Task PutObject_Test10(IMinioClient minio)
var contentType = "binary/octet-stream";
var percentage = 0;
var totalBytesTransferred = 0L;
var progress = new Progress<ProgressReport>(progressReport =>
var progress = new SyncProgress<ProgressReport>(progressReport =>
{
percentage = progressReport.Percentage;
totalBytesTransferred = progressReport.TotalBytesTransferred;
Expand Down
29 changes: 29 additions & 0 deletions Minio/Helper/SyncProgress.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace Minio.Helper;

/// <summary>
/// SyncProgress is a thread-free alternative to <see cref="System.Progress&lt;T&gt;" />
/// and should be used if progress needs be determined in real-time.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <remarks>
/// The upload process uses asynchronous tasks to perform the upload,
/// so these events may be invoked on an arbitrary thread. Use the
/// regular <see cref="System.Progress&lt;T&gt;" /> if you need progress
/// to be reported on a fixed thread or provide your own thread
/// synchronization. Doing synchronous calls to other threads from
/// within this handler will degrade your upload performance.
/// </remarks>
public class SyncProgress<T> : IProgress<T>
{
private readonly Action<T> handler;

public SyncProgress(Action<T> handler)
{
this.handler = handler;
}

public void Report(T value)
{
handler(value);
}
}
Loading