gpt4 book ai didi

c# - 使用带有进度报告的 Async/Await 下载并提取 zip 文件

转载 作者:太空宇宙 更新时间:2023-11-03 23:30:50 25 4
gpt4 key购买 nike

我想实现一个可重用的类,该类将有助于下载给定的 zip 文件并将其解压缩,同时使用 C# 5 等待/异步功能报告进度。

我对此很陌生,目前正在努力解决这个问题。到目前为止,这是我的安装程序类:

class Installer
{
Button saveButton;
ProgressBar progressBar;
Label statusLabel;
Boolean downloadDone;

public Installer(Button _saveButton, ProgressBar _progressBar, Label _statusLabel)
{
saveButton = _saveButton;
progressBar = _progressBar;
statusLabel = _statusLabel;
}

public async void Start(string fileUrl)
{
saveButton.BeginInvoke((Action)(() => {
saveButton.Enabled = false;
}));

Task<bool> downloadArchiveTask = DownloadArchiveAsync(fileUrl);

bool downloadArchiveDone = await downloadArchiveTask;

if (downloadArchiveDone)
statusLabel.BeginInvoke((Action)(() => {
statusLabel.Text = "Download Completed";
}));
}

async Task<bool> DownloadArchiveAsync(string fileUrl)
{
var downloadLink = new Uri(fileUrl);
var saveFilename = Path.GetFileName(downloadLink.AbsolutePath);

DownloadProgressChangedEventHandler DownloadProgressChangedEvent = (s, e) =>
{
progressBar.BeginInvoke((Action)(() => {
progressBar.Value = e.ProgressPercentage;
}));

var downloadProgress = string.Format("{0} MB / {1} MB",
(e.BytesReceived / 1024d / 1024d).ToString("0.00"),
(e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00"));

statusLabel.BeginInvoke((Action)(() => {
statusLabel.Text = "Downloading " + downloadProgress + " ...";
}));
};

AsyncCompletedEventHandler AsyncCompletedEvent = (s, e) =>
{
// Todo: Extract
downloadDone = true;
};

using (WebClient webClient = new WebClient())
{
webClient.DownloadProgressChanged += DownloadProgressChangedEvent;
webClient.DownloadFileCompleted += AsyncCompletedEvent;
webClient.DownloadFileAsync(downloadLink, saveFilename);
}

while (!downloadDone) ;

return true;
}
}

我是这样用的:

(new Installer(startBtn, progressBar, statusLabel)).Start("http://nginx.org/download/nginx-1.9.4.zip");

我不完全确定我是否正确实现了这一点。 Visual Studio 给我以下警告:

DownloadArchiveAsync - This async method lacks 'await' operators and will run synchronously.

另请注意;我目前没有合适的方法来检测下载何时完成,所以我正在使用 boolwhile 循环 - 不确定是否也推荐这样做。

使用 async/await 异步下载 zip 文件并报告进度的正确方法是什么?


编辑

在深入研究之后,我找到了一种可能的解决方案。我已经实现了这个方法:

async Task IsDownloadDone()
{
await Task.Run(() =>
{
while (!downloadDone) ;
});
}

并像这样更新了 DownloadArchiveAsync 返回:

await IsDownloadDone();
return true;

完整代码现在如下所示:http://pastebin.com/MuW0386K

这是实现它的正确方法吗?

最佳答案

你可以用这样的东西替换 DownloadArchiveAsync,它实际上会异步工作:

async Task<bool> DownloadArchiveAsync( string fileUrl )
{
var downloadLink = new Uri( fileUrl );
var saveFilename = System.IO.Path.GetFileName( downloadLink.AbsolutePath );

DownloadProgressChangedEventHandler DownloadProgressChangedEvent = ( s, e ) =>
{
progressBar.BeginInvoke( (Action)(() =>
{
progressBar.Value = e.ProgressPercentage;
}) );

var downloadProgress = string.Format( "{0} MB / {1} MB",
(e.BytesReceived / 1024d / 1024d).ToString( "0.00" ),
(e.TotalBytesToReceive / 1024d / 1024d).ToString( "0.00" ) );

statusLabel.BeginInvoke( (Action)(() =>
{
statusLabel.Text = "Downloading " + downloadProgress + " ...";
}) );
};

using (WebClient webClient = new WebClient())
{
webClient.DownloadProgressChanged += DownloadProgressChangedEvent;
await webClient.DownloadFileTaskAsync( downloadLink, saveFilename );
}

return true;
}

编辑:我在 MSDN 中找到了 DownloadFileTaskAsync,这让事情变得更漂亮了。

方法上的

async 表示此方法使用 await。因此,请使用“WebClient”中的可等待函数。

关于c# - 使用带有进度报告的 Async/Await 下载并提取 zip 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32269667/

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