Skip to content

Instantly share code, notes, and snippets.

@nikkonrom
Last active March 30, 2018 16:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nikkonrom/fa3f156e3f989209db74dca6e9838007 to your computer and use it in GitHub Desktop.
Save nikkonrom/fa3f156e3f989209db74dca6e9838007 to your computer and use it in GitHub Desktop.
using System;
using System.Net;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace test
{
static class Program
{
public static void Main(string[] args)
{
var cts = new CancellationTokenSource();
AsyncDownloadAndWrite(cts.Token);
while (true)
{
ConsoleKeyInfo keyInfo = Console.ReadKey();
if (keyInfo.Key == ConsoleKey.Backspace)
{
cts.Cancel();
break;
}
}
Console.ReadKey();
}
public static async Task AsyncDownloadAndWrite(CancellationToken token)
{
var client = new WebClient();
TextProgressBar progressBar = new TextProgressBar(client);
progressBar.StartDrawing();
try
{
Console.WriteLine(await DownloadAsync(client, new Uri("http://ftp.byfly.by/test/100mb.txt"), token));
}
catch (TaskCanceledException exception)
{
Console.WriteLine(exception.Message);
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
throw;
}
}
public static async Task<string> DownloadAsync(WebClient client, Uri uri, CancellationToken token)
{
var taskCompletionSource = new TaskCompletionSource<string>();
client.DownloadStringCompleted += SetResultAction;
void SetResultAction(object sender, DownloadStringCompletedEventArgs data)
{
if (data.Cancelled)
{
taskCompletionSource.SetCanceled();
}
else if (data.Error != null)
{
taskCompletionSource.SetException(data.Error);
}
else
{
taskCompletionSource.SetResult(data.Result);
}
client.DownloadStringCompleted -= SetResultAction;
}
using (token.Register(client.CancelAsync))
{
client.DownloadStringAsync(uri);
return await taskCompletionSource.Task;
}
}
}
class TextProgressBar
{
private readonly object _synchronizationObject;
private readonly WebClient _client;
public TextProgressBar(WebClient client)
{
_client = client;
Console.CursorVisible = false;
_synchronizationObject = new object();
}
public void StartDrawing()
{
_client.DownloadProgressChanged += (sender, eventArgs) => Draw(eventArgs.BytesReceived, eventArgs.TotalBytesToReceive);
}
private void Draw(long progress, long total)
{
lock (_synchronizationObject)
{
Console.CursorLeft = 0;
Console.Write("[");
Console.CursorLeft = 32;
Console.Write("]");
Console.CursorLeft = 1;
var oneChunk = 30.0f / total;
var position = 1;
for (var i = 0; i < oneChunk * progress; i++)
{
Console.CursorLeft = position++;
Console.Write("#");
}
for (var i = position; i <= 31; i++)
{
Console.CursorLeft = position++;
Console.Write(".");
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment