我目前正在开发一款小型迷你游戏。游戏可以打开一些选项,例如,在选项中可以单击"启用音乐"。因为包括音频文件在内的应用程序太大了,我希望用户选择他是否想要音乐,是否必须下载。
我正在为这个选项使用异步任务,因为选项应该在下载时弹出,这是我迄今为止的代码:
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:UsersPublicDocumentsUltimate Tic-Tac-ToeAudios"), 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个文件,完成!但是代码直接跳转到"DownloadFileCompleted",所以这是不起作用的。我在这里坐了大约两个小时,到处乱弄。
我如何让异步任务创建一个由两个文件组成的"Que",下载它们,然后跳到"DownloadFileCompleted"并仍然显示进度?非常感谢。
理解异步等待可能有用的东西可能是Eric Lippert的餐厅比喻,它很好地解释了为什么要使用异步等待,以及在哪些情况下不使用。在页面中间的某个地方搜索问题异步和并行之间有什么区别
Stephen Cleary在这篇文章中解释了的基本原理
异步等待的好处是,你的程序看起来是顺序的,可以像顺序的一样读取,而事实上,一旦它必须等待某个东西,你的线程就会四处寻找,如果它可以做其他事情而不是等待。在埃里克·利珀特的餐厅比喻中:与其等到面包烤好,不如开始烧水泡茶。
您忘记做的一件事就是等待异步下载。正如Stephen Cleary所解释的,只有当您在返回Task时声明函数async时,才能做到这一点:
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;
}