2011-08-14 5 views
3

J'écris un programme de téléchargement en masse très simple en C# qui lit un fichier .txt d'URL à télécharger. Je l'ai mis en place avec un thread global et un délégué pour la mise à jour de l'interface graphique, et l'appui sur le bouton "Begin" crée et démarre ce thread. Ce que je veux faire est d'avoir un bouton "Pause" qui me permet de mettre en pause le téléchargement jusqu'à ce que je clique sur le bouton "Reprendre". Comment puis-je faire cela?Mettre en pause un fil de téléchargement

Le code correspondant:

private Thread thr; 
private delegate void UpdateProgressCallback(int curFile); 

private void Begin_btn_Click(object sender, EventArgs e) 
{ 
    thr = new Thread(Download); 
    thr.Start(); 
} 

private void Pause_btn_Click(object sender, EventArgs e) 
{ 
    Pause_btn.Visible = false; 
    Resume_btn.Visible = true; 
    //{PAUSE THREAD thr} 
} 

private void Resume_btn_Click(object sender, Eventargs e) 
{ 
    Pause_btn.Visible = true; 
    Resume_btn.Visible = false; 
    //{RESUME THREAD thr} 
} 

public void Download() 
{ 
    //Download code goes here 
} 

De toute évidence, je ne suis pas l'aide d'un travailleur, et je ne souhaite vraiment pas, sauf si vous pouvez me montrer comment le faire fonctionner (je ne comprends pas vraiment ouvriers). Toute aide serait appréciée.

+2

Je ne suis pas un expert C#, mais je crois que cela dépendra fortement de ** comment ** vous téléchargez le fichier. Quel est le code actuel dans 'Download()'? – jtbandes

+4

vous devrez probablement mettre fin à la connexion http et le rétablir sur CV. TCP expirera autrement. – sleeplessnerd

+1

Si vous arrêtez le téléchargement, alors vous devez redémarrer, vous devrez également garder la trace de l'endroit où vous vous êtes arrêté et peut-être télécharger et ignorer ces parties, ou recommencer votre téléchargement à nouveau. –

Répondre

2

Si vous utilisez la méthode System.Net.WebClient.DownloadFile() ou System.Net.WebClient.DownloadFileAsync() alors vous ne pouvez pas mettre en pause le téléchargement. La différence entre ces méthodes est que la dernière méthode démarre un téléchargement asynchrone, donc vous n'aurez pas besoin de créer un thread distinct si vous utilisez cette méthode. Malheureusement, les téléchargements exécutés avec l'une ou l'autre méthode ne peuvent pas être suspendus ou repris. Vous devez utiliser System.Net.HttpWebRequest. Essayez quelque chose comme ceci:

class Downloader 
{ 
    private const int chunkSize = 1024; 
    private bool doDownload = true; 

    private string url; 
    private string filename; 

    private Thread downloadThread; 

    public long FileSize 
    { 
     get; 
     private set; 
    } 
    public long Progress 
    { 
     get; 
     private set; 
    } 

    public Downloader(string Url, string Filename) 
    { 
     this.url = Url; 
     this.filename = Filename; 
    } 

    public void StartDownload() 
    { 
     Progress = 0; 
     FileSize = 0; 
     commenceDownload(); 
    } 

    public void PauseDownload() 
    { 
     doDownload = false; 
     downloadThread.Join(); 
    } 

    public void ResumeDownload() 
    { 
     doDownload = true; 
     commenceDownload(); 
    } 

    private void commenceDownload() 
    { 
     downloadThread = new Thread(downloadWorker); 
     downloadThread.Start(); 
    } 

    public void downloadWorker() 
    { 
     // Creates an HttpWebRequest with the specified URL. 
     HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url); 

     FileMode filemode; 
     // For download resume 
     if (Progress == 0) 
     { 
      filemode = FileMode.CreateNew; 
     } 
     else 
     { 
      filemode = FileMode.Append; 
      myHttpWebRequest.AddRange(Progress); 
     } 

     // Set up a filestream to write the file 
     // Sends the HttpWebRequest and waits for the response.   
     using (FileStream fs = new FileStream(filename, filemode)) 
     using (HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse()) 
     { 
      // Gets the stream associated with the response. 
      Stream receiveStream = myHttpWebResponse.GetResponseStream(); 

      FileSize = myHttpWebResponse.ContentLength; 

      byte[] read = new byte[chunkSize]; 
      int count; 


      while ((count = receiveStream.Read(read, 0, chunkSize)) > 0 && doDownload) 
      { 
       fs.Write(read, 0, count); 
       count = receiveStream.Read(read, 0, chunkSize); 

       Progress += count; 
      } 
     } 
    } 
} 

J'utilise un code de HttpWebRequest.GetResponse page sur MSDN.

Au lieu d'arrêter le fil sur pause et démarrer une nouvelle Tens, vous pouvez également changer la boucle while attendre jusqu'à ce que le téléchargement est repris comme suit:

  while ((count = receiveStream.Read(read, 0, chunkSize)) > 0) 
      { 
       fs.Write(read, 0, count); 
       count = receiveStream.Read(read, 0, chunkSize); 

       Progress += count; 

       while(!doDownload) 
        System.Threading.Thread.Sleep(100); 
      } 

Le bon côté est que vous pouvez être capable de réutiliser le même fil. L'inconvénient est que la connexion peut expirer et se fermer. Dans ce dernier cas, vous devrez le détecter et vous reconnecter.

Vous pouvez également ajouter un événement lorsque le téléchargement est terminé.

+1

S'il vous plaît, ne conseillez pas aux autres d'utiliser 'Thread.Abort()' à moins que ce ne soit complètement nécessaire. Cette méthode devrait être vraiment évitée. – svick

+0

Je ne connais pas d'autre moyen de faire ce que l'affiche veut. Je ne suis pas au courant d'un moyen géré pour obtenir _n_ octets à partir d'un flux Web (synchrone ou autre). S'il vous plait corrigez moi si je me trompe. – Serge

+1

Vous avez tort. Vous devez accéder au * flux *, alors il est trivial d'arrêter de descendre les octets et d'arrêter/suspendre la lecture à tout moment. Thread.Abort() est presque toujours une idée * mauvaise *. –

Questions connexes