Hangfire.Console
Hangfire.Console copied to clipboard
Replace or extend the IProgressBar interface to use IProgress<T>
There is a standard progress interface in .NET called IProgress<T> which, while a method signature is different, covers the existing interface's type of functionality.
It is easier to use this interface as it doesn't require the Hangfire.Console dependency across all libraries in a code base that need to provide progress.
I do understand a reluctance to fully replace IProgressBar as it would be a breaking change as well as IProgressBar allows int and double for values. What might be a fair middle ground (though still breaking) is to have IProgressBar extend both IProgress<int> and IProgress<double>.
I have the following class to solve this issue:
public static class ProgressBarExtensionMethods
{
public static IProgress<T> AsIProgress<T>(this IProgressBar progressBar, Func<T, double> convert)
{
return new ProgressConverter<T>(progressBar, convert);
}
private class ProgressConverter<T> : IProgress<T>
{
IProgressBar progressBar;
Func<T, double> convert;
public ProgressConverter(IProgressBar progressBar, Func<T, double> convert)
{
this.progressBar = progressBar;
this.convert = convert;
}
public void Report(T value)
{
progressBar.SetValue(convert(value));
}
}
}
When using FluentFtp i can just do this:
var progress = context.WriteProgressBar().AsIProgress<FtpProgress>(x => x.Progress);
await client.UploadFileAsync(sourcePath, destinationPath, FtpExists.Overwrite, progress: progress, token: cancellationToken).ConfigureAwait(false);
Works great!
Thanks @Peter-Optiway - I might use something similar to that in my project though would still be nice to have IProgressBar<> built-into the library itself. I'd be happy to write that PR though I don't know if the maintainer would accept that change.
Indeed, I’ve mistakenly thought that interface was not available for old .NET Classic frameworks.
I‘m thinking of adding a new IProgressBar<T> interface extending both IProgressBar and IProgress<T>, and introducing IProgress<T> WriteProgressBar<T>(Func<T, double> converter) extension method. Would that fit your use cases?
I’m a bit busy with other projects at the moment though, so don’t expect it sometime soon. Sorry.
Yeah, a method that returns an IProgress<T> is a good start. Ideally if there was one that already returned a IProgress<double> without a conversion function would be best.
I think it might be a good time to deprecate the current interface and return IProgressBar<double> instead. Internally you are already casting from int to a double.