我目前正在开发一款小型迷你游戏。游戏可以打开一些选项,在选项中你可以点击“启用音乐”。因为应用程序太大了,包括音频文件,我希望用户选择是否需要音乐,并且必须下载它。
我正在为此选项使用Async-Task,因为选项应该在下载时弹出,这是我的代码到目前为止:
public void CheckForFiles()
{
// searches the current directory and sub directory
int fCount = Directory.GetFiles(path, "*", SearchOption.AllDirectories).Length;
//If there are NOT all of the Audiofiles, delete all of them and re-download!
if (fCount != 2)
{
//Just to be sure, delete all previous files!
Array.ForEach(Directory.GetFiles(@"C:\Users\Public\Documents\Ultimate Tic-Tac-Toe\Audios\"), File.Delete);
//Change the Button from "Apply" to "Download"
apply_options.Text = "Download";
//Set the Warning Text
warning_text.Text = "Warning! Downloading the needed Audiofiles. DO NOT interrupt the Proccess!";
//SHow the Download-Progress Bar
download_progress.Visible = true;
//Download all
WebClient webClient = new WebClient();
webClient.DownloadProgressChanged += (s, y) =>
{
download_progress.Value = y.ProgressPercentage;
};
webClient.DownloadFileCompleted += (s, y) =>
{
download_progress.Visible = false;
warning_text.Text = "Complete!";
CheckForFiles();
};
webClient.DownloadFileAsync(new Uri(remoteUri_dark), fileName_dark);
//Text = "Downloading File one of" + WAITLIST;
}
这会下载一个文件,但我需要两个。 所以我试着等待我的进度条填充,下载下一个,如果我有2个文件,完成!但是Code直接进入“DownloadFileCompleted”,所以这不起作用。我现在坐在这里约2个小时,摆弄着。
如何让异步任务创建两个文件的“Que”,下载它们然后跳转到“DownloadFileCompleted”并仍然显示进度? 谢谢!
答案 0 :(得分:3)
Something that might be useful to understand async-await might be Eric Lippert's restaurant metaphor中的href#,这很好地解释了为什么要使用async-await以及在哪种情况下不使用async-await。搜索问题页面的一半 Asynchrony和Parallelism之间有什么区别?
Stephen Cleary explains the basics in this article
async-await的好处在于你的程序看起来是顺序的,并且可以按顺序读取,而事实上,只要它必须等待你的线程环顾四周,如果它可以做其他事情而不是等待。在埃里克·利珀特(Eric Lippert)的餐厅比喻中:不要等到面包烤好,而是开始用水煮茶。
您忘记做的一件事就是等待下载异步。正如Stephen Cleary解释的那样,只有在返回任务时声明函数异步才能执行此操作:
public async Task CheckForFiles()
{
// let your thread do all the things sequentially, until it has to wait for something
// you don't need the events, just await for the DownloadAsync to complete
download_progress.Visible = true;
//Download all
WebClient webClient = new WebClient();
await webClient.DownloadFileAsync(new Uri(remoteUri_dark), fileName_dark);
// if here, you know the first download is finished
ShowProgressFirstFileDownloaded();
await webClient.DownloadFileAsync( /* 2nd file */);
// if here: 2nd file downloaded
ShowProgess2ndFileDownLoaded();
download_progress.Visible = false;
}
如果需要,可以同时开始两次下载。这并不总是更快:
public async Task CheckForFiles()
{
... do the preparations
//Download all
download_progress.Visible = true;
WebClient webClient = new WebClient();
var taskDownload1 = webClient.DownloadFileAsync(/* params 1st file */);
// do not await yet, start downloading the 2nd file
var taskDownload2 = webClient.DownloadFileAsync( /* params 2nd file */);
// still do not await, first show the progress
ShowProgessDownloadStarted();
// now you have nothing useful to do, await until both are finished:
await Task.WhenAll(new Task[] {taskDownload1, taskDownload2});
// if here, both tasks finished, so:
download_progress.Visible = false;
}