2011-08-14 9 views
3

ダウンロードするURLの.txtファイルを読み込む、非常に単純な一括ダウンロードプログラムをC#で作成しています。私はGUIを更新するためにグローバルなスレッドとデリゲートを設定し、 "Begin"ボタンを押すとそのスレッドが作成されて開始されます。私がしたいのは、 "Resume"ボタンを押すまでダウンロードを一時停止できる「一時停止」ボタンがあることです。これはどうすればいいですか?ダウンロードスレッドを一時停止する

関連するコード:明らか

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 
} 

、私は労働者を使用していない、と私は本当にあなたはそれが仕事を得るためにどのように私を見ることができない限り、したくない(私は本当に理解していません労働者)。どんな助けもありがとう。

+2

私はC#のエキスパートではありませんが、これは*ファイルのダウンロード方法*に依存します。 'Download()'の実際のコードは何ですか? – jtbandes

+4

http接続を終了し、再開時に再確立する必要があるでしょう。それ以外の場合はTCPがタイムアウトします。 – sleeplessnerd

+1

ダウンロードを停止すると、再起動する必要があります。また、停止した場所を追跡し、それらの部分をダウンロードして無視するか、ダウンロードをもう一度やり直す必要があります。 –

答えて

2

System.Net.WebClient.DownloadFile()またはSystem.Net.WebClient.DownloadFileAsync()メソッドを使用する場合、できませんダウンロードを一時停止します。これらのメソッドの違いは、後者のメソッドでは非同期ダウンロードが開始されるため、このメソッドを使用する場合は別途スレッドを作成する必要がないことです。残念ながら、いずれの方法で実行されたダウンロードも一時停止または再開できません。

System.Net.HttpWebRequestを使用する必要があります。

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; 
      } 
     } 
    } 
} 

私はHttpWebRequest.GetResponseのコードをMSDNで使用しました。

代わりに一時停止のスレッドを停止し、再開に新しいものを始めるので、あなたもダウンロードが次のように再開されるまで待つようにwhileループを変更することができます。

  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); 
      } 

アップ側は、あなたがかもしれないということです同じスレッドを再利用できるようにする。下側は、接続がタイムアウトして閉じられることです。後者の場合、これを検出して再接続する必要があります。

donwloadが完了したときにイベントを追加することもできます。

+1

完全に必要でない限り、 'Thread.Abort()'を使用するように他の人に助言してはいけません。その方法は本当に避けなければならない。 – svick

+0

私はポスターが望んでいることをするための他の方法を知らない。私は_n_バイトをWebストリームから(同期的にまたは別の方法で)取得する管理された方法を認識していません。私が間違っていれば私を修正してください。 – Serge

+1

あなたは間違っています。あなたは*ストリーム*にアクセスする必要があります。それから、バイトをプルダウンするのをやめ、いつでも読みを停止/一時停止するのは簡単です。 Thread.Abort()はほとんど常に*悪い*アイデアです。 –