2014-01-08 66 views
0

我面臨另一個問題,我的應用程序從網上下載文件,提取它,刪除它等,它運行良好的第一次運行,然後當涉及到下載下一個文件它只是凍結下載並永遠掛在那裏..這可能是嘗試打開一個已經打開的連接的東西,但我不知道如何關閉它,這是我第一次與C#聯網,而且我是自學的。下載後WebClient凍結

我的代碼:

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() ; 
     }  
    } 
+0

你可以斷點到versionCheck()嗎?它到達那裏了嗎?第一次下載完成後,您的表單是否被鎖定?我不記得了,但如果是這種情況,'DownloadFileCompleted'事件可能會回調到主窗體線程中。另外,嘗試將'DownloadFileCompleted'調用移動到'DownloadFileAsync'上方的行。考慮到文件可能很大,這可能不會做任何事情,但無論如何這是一個好主意。 – Brandon

+0

此外,您將重新聲明變量作爲不同類型的地方。 – Brandon

+0

是的,我認爲重新宣佈它們會更容易,而不是用不同的名稱創建新的,只是爲了不會迷路,我相信當我重新聲明它們時,它會擺脫舊的,是我錯誤?請糾正我的錯誤,如果你可能:) 而一切正常,事情是它應該下載3個文件連續,它只下載一個,當它開始下載第二個,它顯示它的大小= 0字節在磁盤上,直到我重新啓動它。 –

回答

0

如果你使用異步操作,你需要使用async和await關鍵字。

當完成下載或失敗時,您需要處理或關閉您的web客戶端。

由於b1tsh1ft聲明最好的事情是使用using語句。

string version = versionInfo.ProductVersion; 
string[] nversion = version.Split('.'); 

int version = Int32.Parse(updateversion); 
string nversion = (version + 1).ToString(); 

是不是你的VS沒有在編輯器中給出一個矛盾的錯誤呢?

+0

不是沒有,這讓我覺得它是像PHP ,新的價值超越了舊的價值,我知道現在你們都說它不行。我會編輯它,看看它是如何工作的。 –

0

首先,你應該把Web客戶端在使用塊,因爲它實現IDisposable

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

不要使用異步版本。一個異常可能被拋出,並在另一個線程上丟失。首先定期測試並定期開展工作。

還將您的StreamReader(或任何實現IDisposable的內容)放入using()語句中。手動調用處置會更可靠,因爲即使在失敗時也能處理。

+0

這是否意味着我應該把使用塊之後代碼的提取部分?我嘗試做不同的事情的主要問題是提取在下載完成之前開始,這就是爲什麼我使用異步,謝謝你的信息,雖然,我會試試:) –