下载后网络客户端冻结



我遇到了另一个问题,我的应用程序从 Web 下载文件,提取它,删除它等等,它在第一次运行时运行良好,然后在下载下一个文件时,它只是冻结下载并永远挂在那里..这可能是尝试打开一个已经打开的连接,但我不知道如何关闭它,这是我第一次与 C# 联网,我是自学。

我的代码:

  public void start() {
        if (File.Exists("Data/version.txt")) { File.Delete("Data/version.txt"); }
        label1.Text = "Getting update information...";
        WebClient webClient = new WebClient();
        webClient.DownloadFileAsync(new Uri("http://127.0.0.1/update/version.txt"), @"Data/version.txt");
        webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(versionCompleted);
    }
    private void versioncheck() {
        if (File.Exists("Main.exe"))
        {       
            label1.Text = "Contacting update server...";
                var versionInfo = FileVersionInfo.GetVersionInfo("Main.exe");
                string version = versionInfo.ProductVersion;
                string[] nversion = version.Split('.');
                string updateversion = nversion[3];
                int version = Int32.Parse(updateversion);
                ///////////////////////////////////////////////////////////
                StreamReader sr = new StreamReader("Data/version.txt");
                ///////////////////////////////////////////////////////////
                string readline = sr.ReadLine();
                sr.Dispose();
                int serverversion = Int32.Parse(readline);
                if (serverversion > version) {
                    string filenumber = (version+1).ToString();
                    downloadfile(filenumber); 
                }
                else if(serverversion == version){
                    label1.Text = "Game is up to date!";
                    startButton.Enabled = true;
                }
        }
        else { MessageBox.Show("Unexpected Error!", "Error!"); }
    }
    private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        progressBar1.Value = e.ProgressPercentage;
    }
    private void Completed(object sender, AsyncCompletedEventArgs e)
    {
        label1.Text = "Extracting Files...";
        var versionInfo = FileVersionInfo.GetVersionInfo("Main.exe");
        string version = versionInfo.ProductVersion;
        string[] nversion = version.Split('.');
        string updateversion = nversion[3];
        int version = Int32.Parse(updateversion); string nversion = (version + 1).ToString();
        Process proc = Process.Start("update"+nversion+".exe"); // extract in the silent mode
        proc.WaitForExit();
        File.Delete("update" + nversion + ".exe");
        label1.Text = "Checking for more updates...";
        versioncheck();
    }
    private void versionCompleted(object sender, AsyncCompletedEventArgs e) {
        versioncheck();
    }
    private void downloadfile(string filenumber)
    {
        try
        {
            //MessageBox.Show("Download working");
            System.Net.WebClient webClient = new System.Net.WebClient();
            webClient.OpenRead("http://127.0.0.1/Update/update" + filenumber + ".exe");
            Int64 bytes_total = Convert.ToInt64(webClient.ResponseHeaders["Content-Length"]);
            string updatelength = Convert.ToString((bytes_total / 1024).ToString());
            label2.Text = "File size:" + updatelength + "KB";
            ////////////////////////////////////////////////////
            label1.Text = "Downloading Update...";
            webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
            webClient.DownloadFileAsync(new Uri("http://127.0.0.1/Update/update" + filenumber + ".exe"), @"update"+filenumber+".exe");
            webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
            webClient.Dispose();
        }
        catch (WebException )
        {
            MessageBox.Show("Connection error!", "Error!");
            Application.Exit();
        }
        catch (IOException)
        {
            MessageBox.Show("Unknown Error!", "Error!");
            Application.Exit() ;
        }       
    }

如果你使用异步操作,你需要使用async和await关键字。

您需要在完成下载或失败时释放或关闭 Web 客户端。

正如 b1tsh1ft 所说,最好的办法是使用 using 语句。

string version = versionInfo.ProductVersion;
string[] nversion = version.Split('.');
int version = Int32.Parse(updateversion); 
string nversion = (version + 1).ToString();

您的VS不是没有在编辑器中给出与此冲突的错误吗?

首先,您应该将WebClient放在使用块中,因为它实现了IDisposable

using(var webClient = new WebClient())
{
    // do work here
    webClient.DownloadFile(..)
}

不要使用异步版本。可能会引发异常,并在另一个线程上丢失。首先测试并使其定期工作。

同时将 StreamReader(或任何实现 IDisposable 的东西)放在 using() 语句中。它比手动调用 dispose 更可靠,因为它即使在失败时也会释放。

最新更新