Redpoint.ProgressMonitor
2023.150.450
Prefix Reserved
See the version list below for details.
dotnet add package Redpoint.ProgressMonitor --version 2023.150.450
NuGet\Install-Package Redpoint.ProgressMonitor -Version 2023.150.450
<PackageReference Include="Redpoint.ProgressMonitor" Version="2023.150.450" />
paket add Redpoint.ProgressMonitor --version 2023.150.450
#r "nuget: Redpoint.ProgressMonitor, 2023.150.450"
// Install Redpoint.ProgressMonitor as a Cake Addin #addin nuget:?package=Redpoint.ProgressMonitor&version=2023.150.450 // Install Redpoint.ProgressMonitor as a Cake Tool #tool nuget:?package=Redpoint.ProgressMonitor&version=2023.150.450
Redpoint.ProgressMonitor
This library provides APIs for monitoring and reporting the progress of arbitrary operations in console applications.
Read on for the following examples:
Example for a generic stream
You can monitor an operation that uses a stream like so:
// Inject these services.
IProgressFactory _progressFactory;
IMonitorFactory _monitorFactory;
using (var stream = new FileStream(...))
{
// Start monitoring.
var cts = new CancellationTokenSource();
var progress = _progressFactory.CreateProgressForStream(stream);
var monitorTask = Task.Run(async () =>
{
var consoleWidth = 0;
try
{
consoleWidth = Console.BufferWidth;
}
catch
{
// Not connected to a console, e.g. output is
// redirected.
}
var monitor = _monitorFactory.CreateByteBasedMonitor();
await monitor.MonitorAsync(
progress,
null,
(message, count) =>
{
if (consoleWidth != 0)
{
// Emit the progress information in such a
// way that we overwrite the previous info
// reported to the console.
Console.Write($"\r{message}".PadRight(consoleWidth));
}
else
{
// Emit onto a new line every 5 seconds. This
// callback is invoked every 100ms.
if (count % 50 == 0)
{
Console.WriteLine(message);
}
}
},
cts.Token);
});
// e.g. hash the stream.
byte[] hashBytes;
using (var hasher = SHA256.Create())
{
hashBytes = await hasher.ComputeHashAsync(stream);
}
// Stop monitoring.
cts.Cancel();
try
{
await monitorTask;
}
catch (OperationCanceledException) { }
// Emit a newline after our progress message.
if (consoleWidth != 0)
{
Console.WriteLine();
}
}
Example for a HTTP download
If you're reporting progress on a HTTP stream, there's a few extra things to keep in mind:
- You need to pass
HttpCompletionOption.ResponseHeadersRead
as the completion option, orHttpClient
will buffer the entire response by default. - You need to wrap the stream you read from in
PositionAwareStream
, which is a class provided by this library. Since the underlying HTTP stream does not supportPosition
orLength
, this wrapping stream tracks the position as the stream is read from and allows the length to be passed in as a constructor parameter (which you should set based on the Content-Length header).
Below is a concise example of how to show the progress of downloading a file:
using (var client = new HttpClient())
{
using (var target = new FileStream(targetPath, FileMode.Create, FileAccess.Write, FileShare.None))
{
var response = await client.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead);
using (var stream = new PositionAwareStream(
await response.Content.ReadAsStreamAsync(),
response.Content.Headers.ContentLength!.Value))
{
var cts = new CancellationTokenSource();
var progress = _progressFactory.CreateProgressForStream(stream);
var monitorTask = Task.Run(async () =>
{
var consoleWidth = 0;
try
{
consoleWidth = Console.BufferWidth;
}
catch { }
var monitor = _monitorFactory.CreateByteBasedMonitor();
await monitor.MonitorAsync(
progress,
null,
(message, count) =>
{
if (consoleWidth != 0)
{
Console.Write($"\r{message}".PadRight(consoleWidth));
}
else if (count % 50 == 0)
{
Console.WriteLine(message);
}
},
cts.Token);
});
await stream.CopyToAsync(target);
cts.Cancel();
try
{
await monitorTask;
}
catch (OperationCanceledException) { }
}
}
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net7.0
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Redpoint.ProgressMonitor:
Package | Downloads |
---|---|
Redpoint.PackageManagement
Provides APIs for installing, upgrading and uninstalling packages with WinGet and Homebrew. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
2023.1176.407 | 174 | 6/25/2023 |
2023.1176.396 | 143 | 6/25/2023 |
2023.1176.363 | 155 | 6/25/2023 |
2023.1176.360 | 188 | 6/25/2023 |
2023.1175.638 | 149 | 6/24/2023 |
2023.1170.907 | 143 | 6/19/2023 |
2023.1170.900 | 149 | 6/19/2023 |
2023.1167.562 | 144 | 6/16/2023 |
2023.1167.556 | 146 | 6/16/2023 |
2023.1167.496 | 159 | 6/16/2023 |
2023.1166.1008 | 162 | 6/15/2023 |
2023.1166.938 | 135 | 6/15/2023 |
2023.1166.713 | 156 | 6/15/2023 |
2023.1166.699 | 143 | 6/15/2023 |
2023.1165.1065 | 151 | 6/14/2023 |
2023.1165.888 | 150 | 6/14/2023 |
2023.1165.878 | 152 | 6/14/2023 |
2023.1165.861 | 139 | 6/14/2023 |
2023.1165.828 | 153 | 6/14/2023 |
2023.1165.686 | 166 | 6/14/2023 |
2023.1165.653 | 146 | 6/14/2023 |
2023.377.1003 | 228 | 5/31/2023 |
2023.377.909 | 165 | 5/31/2023 |
2023.377.558 | 165 | 5/31/2023 |
2023.365.1417 | 213 | 5/30/2023 |
2023.365.1350 | 150 | 5/30/2023 |
2023.365.1327 | 147 | 5/30/2023 |
2023.365.1306 | 163 | 5/30/2023 |
2023.365.1198 | 175 | 5/30/2023 |
2023.365.1046 | 152 | 5/30/2023 |
2023.365.710 | 151 | 5/30/2023 |
2023.365.703 | 163 | 5/30/2023 |
2023.365.336 | 153 | 5/30/2023 |
2023.174.636 | 153 | 6/14/2023 |
2023.174.616 | 135 | 6/14/2023 |
2023.174.442 | 145 | 6/14/2023 |
2023.162.1243 | 139 | 6/13/2023 |
2023.162.1225 | 146 | 6/13/2023 |
2023.162.1023 | 135 | 6/13/2023 |
2023.162.948 | 138 | 6/13/2023 |
2023.162.865 | 149 | 6/13/2023 |
2023.162.770 | 168 | 6/13/2023 |
2023.162.734 | 163 | 6/13/2023 |
2023.162.701 | 152 | 6/13/2023 |
2023.162.470 | 165 | 6/13/2023 |
2023.162.418 | 147 | 6/13/2023 |
2023.150.1142 | 148 | 6/12/2023 |
2023.150.1121 | 150 | 6/12/2023 |
2023.150.1095 | 146 | 6/12/2023 |
2023.150.1081 | 135 | 6/12/2023 |
2023.150.1066 | 146 | 6/12/2023 |
2023.150.999 | 135 | 6/12/2023 |
2023.150.916 | 164 | 6/12/2023 |
2023.150.865 | 150 | 6/12/2023 |
2023.150.831 | 148 | 6/12/2023 |
2023.150.774 | 144 | 6/12/2023 |
2023.150.613 | 141 | 6/12/2023 |
2023.150.558 | 157 | 6/12/2023 |
2023.150.456 | 171 | 6/12/2023 |
2023.150.450 | 172 | 6/12/2023 |
2023.150.220 | 168 | 6/12/2023 |
2023.150.179 | 175 | 6/12/2023 |
2023.150.167 | 170 | 6/12/2023 |
2023.138.864 | 161 | 6/11/2023 |
2023.138.837 | 156 | 6/11/2023 |
2023.138.363 | 166 | 6/11/2023 |
2023.138.224 | 191 | 6/11/2023 |
2023.138.213 | 140 | 6/11/2023 |
2023.126.1167 | 169 | 6/11/2023 |
2023.126.1148 | 161 | 6/10/2023 |
2023.126.838 | 172 | 6/10/2023 |
2023.126.794 | 167 | 6/10/2023 |
2023.126.745 | 169 | 6/10/2023 |
2023.126.714 | 179 | 6/10/2023 |
2023.126.662 | 176 | 6/10/2023 |
2023.114.544 | 150 | 6/9/2023 |
2023.114.351 | 162 | 6/9/2023 |
2023.90.1030 | 167 | 6/7/2023 |
2023.90.1009 | 150 | 6/7/2023 |
2023.54.1152 | 149 | 6/4/2023 |
2023.54.419 | 165 | 6/4/2023 |
2023.54.198 | 150 | 6/4/2023 |
2023.54.60 | 132 | 6/4/2023 |
2023.54.48 | 159 | 6/4/2023 |
2023.42.745 | 151 | 6/3/2023 |
2023.30.1191 | 145 | 6/2/2023 |
2023.30.1172 | 165 | 6/2/2023 |
2023.30.1163 | 152 | 6/2/2023 |
2023.30.1147 | 161 | 6/2/2023 |
2023.30.1136 | 171 | 6/2/2023 |
2023.30.765 | 172 | 6/2/2023 |
2023.30.761 | 158 | 6/2/2023 |
2023.30.747 | 175 | 6/2/2023 |
2023.30.734 | 146 | 6/2/2023 |