gpt4 book ai didi

c# - HttpClient 的进度条

转载 作者:IT王子 更新时间:2023-10-29 04:36:09 24 4
gpt4 key购买 nike

我有一个文件下载器功能:

        HttpClientHandler aHandler = new HttpClientHandler();
aHandler.ClientCertificateOptions = ClientCertificateOption.Automatic;
HttpClient aClient = new HttpClient(aHandler);
aClient.DefaultRequestHeaders.ExpectContinue = false;
HttpResponseMessage response = await aClient.GetAsync(url);
InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();

// To save downloaded image to local storage
var imageFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(
filename, CreationCollisionOption.ReplaceExisting);
var fs = await imageFile.OpenAsync(FileAccessMode.ReadWrite);
DataWriter writer = new DataWriter(fs.GetOutputStreamAt(0));

writer.WriteBytes(await response.Content.ReadAsByteArrayAsync());

await writer.StoreAsync();
//current.image.SetSource(randomAccessStream);
writer.DetachStream();
await fs.FlushAsync();

如何实现进度条功能?也许我可以获得到目前为止写入的作者字节?还是什么?

附言我无法使用 DownloadOperation(后台传输),因为来自服务器的数据需要证书 - 而 DownloadOperations 中不存在此功能。

最佳答案

从 .Net 4.5 开始:使用 IProgress<T>

从 .Net 4.5 开始,您可以使用 IProgress<T> 处理异步进度报告界面。您可以使用 HttpClient 编写用于下载文件的扩展方法。可以这样称呼 progressIProgress<float> 的实现对于您的进度条或其他 UI 内容:

// Seting up the http client used to download the data
using (var client = new HttpClient()) {
client.Timeout = TimeSpan.FromMinutes(5);

// Create a file stream to store the downloaded data.
// This really can be any type of writeable stream.
using (var file = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)) {

// Use the custom extension method below to download the data.
// The passed progress-instance will receive the download status updates.
await client.DownloadAsync(DownloadUrl, file, progress, cancellationToken);
}
}

实现

此扩展方法的代码如下所示。请注意,此扩展依赖于另一个用于处理带有进度报告的异步流复制的扩展。

public static class HttpClientExtensions
{
public static async Task DownloadAsync(this HttpClient client, string requestUri, Stream destination, IProgress<float> progress = null, CancellationToken cancellationToken = default) {
// Get the http headers first to examine the content length
using (var response = await client.GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead)) {
var contentLength = response.Content.Headers.ContentLength;

using (var download = await response.Content.ReadAsStreamAsync()) {

// Ignore progress reporting when no progress reporter was
// passed or when the content length is unknown
if (progress == null || !contentLength.HasValue) {
await download.CopyToAsync(destination);
return;
}

// Convert absolute progress (bytes downloaded) into relative progress (0% - 100%)
var relativeProgress = new Progress<long>(totalBytes => progress.Report((float)totalBytes / contentLength.Value));
// Use extension method to report progress while downloading
await download.CopyToAsync(destination, 81920, relativeProgress, cancellationToken);
progress.Report(1);
}
}
}
}

通过流扩展实现真实进度报告:

public static class StreamExtensions
{
public static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, IProgress<long> progress = null, CancellationToken cancellationToken = default) {
if (source == null)
throw new ArgumentNullException(nameof(source));
if (!source.CanRead)
throw new ArgumentException("Has to be readable", nameof(source));
if (destination == null)
throw new ArgumentNullException(nameof(destination));
if (!destination.CanWrite)
throw new ArgumentException("Has to be writable", nameof(destination));
if (bufferSize < 0)
throw new ArgumentOutOfRangeException(nameof(bufferSize));

var buffer = new byte[bufferSize];
long totalBytesRead = 0;
int bytesRead;
while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0) {
await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
totalBytesRead += bytesRead;
progress?.Report(totalBytesRead);
}
}
}

关于c# - HttpClient 的进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20661652/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com