【问题标题】:Wait for DownloadFileAsync to finish downloading and then do something等待 DownloadFileAsync 完成下载,然后做一些事情
【发布时间】:2015-05-13 23:16:15
【问题描述】:

所以基本上我的下载文件是:

public void DownloadFile()
{
    settings_btn.Enabled = false;
    label1.Text = "Checking for updates...";
    //Defines the server's update directory
    string Server = "http://downloadurl/update/";

    //Defines application root
    string Root = AppDomain.CurrentDomain.BaseDirectory;

    //Make sure version file exists
    FileStream fs = null;
    if (!File.Exists("pversion"))
    {
        using (fs = File.Create("pversion")){}
        using (StreamWriter sw = new StreamWriter("pversion")){sw.Write("1.0");}
    }
    //checks client version
    string lclVersion;
    using (StreamReader reader = new StreamReader("pversion"))
    {
        lclVersion = reader.ReadLine();
    }
    decimal localVersion = decimal.Parse(lclVersion);

    //server's list of updates
    XDocument serverXml = XDocument.Load(@Server + "pUpdates.xml");

    //The Update Process
    foreach (XElement update in serverXml.Descendants("pupdate"))
    {
        string version = update.Element("pversion").Value;
        string file = update.Element("pfile").Value;

        decimal serverVersion = decimal.Parse(version);


        string sUrlToReadFileFrom = Server + file;

        string sFilePathToWriteFileTo = Root + file;

        if (serverVersion > localVersion)
        {
            using (webClient = new WebClient())
            {
                webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
                webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);

                // The variable that will be holding the url address (making sure it starts with http://)
                Uri url = new Uri(sUrlToReadFileFrom);

                // Start the stopwatch which we will be using to calculate the download speed
                sw.Start();

                try
                {
                    // Start downloading the file
                    webClient.DownloadFileAsync(url, sFilePathToWriteFileTo);

                    // Change the currently running executable so it can be overwritten.
                    Process thisprocess = Process.GetCurrentProcess();
                    string me = thisprocess.MainModule.FileName;
                    string bak = me + ".bak";
                    if (File.Exists(bak))
                    {
                        File.Delete(bak);
                    }
                    File.Move(me, bak);
                    File.Copy(bak, me);

                    //unzip
                    using (ZipFile zip = ZipFile.Read(file))
                    {
                        foreach (ZipEntry zipFiles in zip)
                        {
                            zipFiles.Extract(Root + "\\", true);
                        }
                    }

                    //download new version file
                    webClient.DownloadFile(Server + "pversion.txt", @Root + "pversion");

                    //Delete Zip File
                    deleteFile(file);

                    var spawn = Process.Start(me);
                    thisprocess.CloseMainWindow();
                    thisprocess.Close();
                    thisprocess.Dispose();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
    }
}

而我的问题是,一旦找到新版本并开始下载文件webClient.DownloadFileAsync(url, sFilePathToWriteFileTo);,它会立即运行下面的代码,即更改名称、解压缩和下载新版本文件的进度

我想要它做的是等待它完成下载文件,然后做剩下的事情。我该怎么做?

-- 如果有必要,ProgressChanged:

private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    label3.Text = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00")) + " " + string.Format("{0} MB's / {1} MB's", (e.BytesReceived / 1024d / 1024d).ToString("0.00"), (e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00"));;
    progressBar1.Value = e.ProgressPercentage;
    label1.Text = e.ProgressPercentage.ToString() + "%";
}

并完成:

private void Completed(object sender, AsyncCompletedEventArgs e)
{
    sw.Reset();
    if (e.Cancelled == true)
    {
        label1.Text = "Download cancelled!";
    }
    else
    {
        label1.Text = "Download completed!";
    }
}

【问题讨论】:

  • 所有操作下载的代码都应该移动到Completed方法,这样它只会在下载完成后执行。目前,如果下载同步运行,您的代码只会等待下载,因为线程会等待。
  • 您使用的是哪个 .NET 框架版本?
  • 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。

标签: c#


【解决方案1】:

您可以使用 DownloadFile 方法。 Async 一词意味着此方法将异步运行(在其他线程中),这就是为什么它会立即进入下一行。 如果要等待下载结束,请使用 DownloadFile 而不是 DownloadFileAsync

【讨论】:

  • 这将使 UI 和应用程序在下载时冻结,这很糟糕!还有很多更好的选择
  • 是的,我注意到,但是,让后台工作人员运行 void 似乎可以解决冻结问题 ^^
  • DownloadFile 不触发进度事件
猜你喜欢
  • 2011-10-09
  • 2021-06-25
  • 1970-01-01
  • 2015-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多