public static Task<byte[]> GetBytesWithProgress(CancellationToken cancelToken, string url, Action<uint> progress)
{
TaskCompletionSource<byte[]> taskCompletion = new TaskCompletionSource<byte[]>();
WebClient client = new WebClient();
int cancelCount = 0;
client.AllowReadStreamBuffering = true;
client.DownloadProgressChanged += (sender, args) =>
{
if (cancelToken.IsCancellationRequested)
{
client.CancelAsync();
}
else
{
progress((uint)args.ProgressPercentage);
}
};
client.OpenReadCompleted += (sender, args) =>
{
if (args.Cancelled)
{
if(cancelCount++ < 5 && !cancelToken.IsCancellationRequested)
client.OpenReadAsync(new Uri(url));
else
taskCompletion.SetCanceled();
}
else if (args.Error != null)
{
if (cancelToken.IsCancellationRequested)
{
taskCompletion.SetCanceled();
}
else
{
taskCompletion.SetException(args.Error);
}
}
else
{
if (cancelToken.IsCancellationRequested)
{
taskCompletion.SetCanceled();
}
else
{
var result = new byte[args.Result.Length];
args.Result.Read(result, 0, (int)args.Result.Length);
taskCompletion.SetResult(result);
}
}
};
client.OpenReadAsync(new Uri(url));
return taskCompletion.Task;
}