使用AsyncTask下载文件并在进度条中显示进度

时间:2016-05-17 10:58:07

标签: c# winforms

我目前正在开发一款小型迷你游戏。游戏可以打开一些选项,在选项中你可以点击“启用音乐”。因为应用程序太大了,包括音频文件,我希望用户选择是否需要音乐,并且必须下载它。

我正在为此选项使用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”并仍然显示进度? 谢谢!

1 个答案:

答案 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;
}