2013-06-12 5 views
0

Je développe une application pour mon propre, En fait, cette application est pour télécharger la dernière version de l'antivirus que nous utilisons dans notre société
dans cette application Je veux utiliser la méthode DownloadFileAsync télécharger mes fichiers, mais il ne fonctionne pas et je reçois cette erreur:ne peut pas télécharger des fichiers multiplie en utilisant DownloadFileAsync

WebClient does not support concurrent I/O operations. 

ceci est mon code source:

private static WebClient wc = new WebClient(); 
     private static ManualResetEvent handle = new ManualResetEvent(true); 
     private DateTime myDate = new DateTime(); 
     private void btn_test_Click(object sender, EventArgs e) 
     { 

      using (WebClient client = new WebClient()) 
      { 
       client.Encoding = System.Text.Encoding.UTF8; 
       var doc = new HtmlAgilityPack.HtmlDocument(); 
       ArrayList result = new ArrayList(); 
       doc.LoadHtml(client.DownloadString("https://www.symantec.com/security_response/definitions/download/detail.jsp?gid=savce")); 
       foreach (var href in doc.DocumentNode.Descendants("a").Select(x => x.Attributes["href"])) 
       { 
        if (href == null) continue; 
        string s = href.Value; 
        Match m = Regex.Match(s, @"http://definitions.symantec.com/defs/(\d{8}-\d{3}-v5i(32|64)\.exe)"); 
        if (m.Success) 
        { 
         Match date = Regex.Match(m.Value, @"(\d{4})(\d{2})(\d{2})"); 
         Match filename = Regex.Match(m.Value, @"\d{8}-\d{3}-v5i(32|64)\.exe"); 
         int year = Int32.Parse(date.Groups[0].Value); 
         int month = Int32.Parse(date.Groups[1].Value); 
         int day = Int32.Parse(date.Groups[3].Value); 

         myDate = new DateTime(
           Int32.Parse(date.Groups[1].Value), 
           Int32.Parse(date.Groups[2].Value), 
           Int32.Parse(date.Groups[3].Value)); 
         listBox1.Items.Add(m.Value); 
         if (myDate == DateTime.Now) 
         { 
          Download(m.Value,filename.Value); 

         } 
         else 
         { 
          MessageBox.Show("There is no Update!"); 
         } 
        } 
       } 

      } 
     } 
     private void Download(string url, string fileName) 
     { 
      wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged); 
      wc.DownloadFileAsync(new Uri(url), @"\\10.1.0.15\Symantec Update Weekly\\" + fileName); 
      //wc.DownloadFile(url, @"\\10.1.0.15\Symantec Update Weekly\\" + fileName); 
     } 

     private void WcOnDownloadFileCompleted(object sender, AsyncCompletedEventArgs e) 
     { 
      if (!e.Cancelled && e.Error == null) 
      { 
       //async download completed successfully 
      } 
      handle.Set(); 
     } 

     private void wc_DownloadProgressChanged(object sender, System.Net.DownloadProgressChangedEventArgs e) 
     { 
      double bytesIn = double.Parse(e.BytesReceived.ToString()); 
      double totalBytes = double.Parse(e.TotalBytesToReceive.ToString()); 
      double percentage = bytesIn/totalBytes * 100; 
      progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString()); 
     } 

lorsque ma demande en essayant de télécharger des fichiers,
il semble que la méthode ci-dessus ne peut pas télécharger plusieurs fichiers en même temps.
J'ai beaucoup cherché et trouvé this solution mais je ne pouvais pas l'appliquer dans mon application.
comment puis-je résoudre cela.
merci à votre avis.

+2

Faire une nouvelle 'WebClient' pour chaque téléchargement? –

+0

@TimS. oui je sais mais comment puis-je transmettre les URL une par une à ma méthode de téléchargement? –

+1

On dirait que vous êtes déjà: vous avez une boucle qui peut appeler 'Download'. Ainsi, il peut passer plusieurs URL, une par une, à votre méthode 'Download'. –

Répondre

3
// Declare a field to hold the Task 
private static Task DownloadTask; 

private Task Download(string url, string fileName) 
{ 
    var wc = new WebClient(); 
    wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged); 
    return wc.DownloadFileTaskAsync(new Uri(url), @"\\10.1.0.15\Symantec Update Weekly\\" + fileName); 
} 

Vous aurez probablement besoin de modifier la barre de progression pour gérer plusieurs threads.

intérieur btn_test_Click

// Before foreach 
var tasks = new List<Task>(); 

// Inside foreach 
if (myDate == DateTime.Now) 
{ 
    MessageBox.Show("Updates are New"); 
} 
else 
{ 
    tasks.Add(Download(m.Value,filename.Value)); 
} 

// After foreach 
// You can also set the TimeSpan value and update the progressbar 
// periodically until all the tasks are finished 
DownloadTask = Task.WhenAll(tasks); 

Voir Task.WaitAll, WebClient.DownloadFileTaskAsync

+0

merci, mais je reçois cette erreur: Impossible de convertir le type 'void' en 'System.Threading.Tasks.Task' à l'intérieur Télécharger la ligne de méthode 'return ...' –

+0

Désolé, changez le 'DownloadFileAsync' à' DownloadFileTaskAsync'. Voir ['WebClient.DownloadFileTaskAsync'] (http://msdn.microsoft.com/en-us/library/hh193917.aspx) – Romoku

+0

merci beaucoup, il fonctionne, mais quand je clique sur btn_test_Click mon application se bloque et ne répond pas à l'entrée Alors que le téléchargement de mes fichiers, et un autre problème est sur la barre de progression (rien d'apprear) –

Questions connexes