DownloadFileAsync陷入循环C#

时间:2018-01-20 08:14:04

标签: c#

我想在网站上下载多个图片。查询链接的格式为:

abc.com/GetImage.aspx?MSSV=0101012018

当我在C#中的 WebClient 类中使用DownloadFileAsync()方法时,如果我只获得1张图片,它仍然有用。但是当我试图获得多个图像时,我把它放在循环中。如果它到达循环,则返回MessageBox包含字符串:"下载完成"或"下载失败"。

但是当我运行它时,当它超出循环时,它会停留在wc_DownloadProgressChanged()方法中,并且永远不会转到wc_DownloadFileComplete()来打印消息。

private void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}
private void wc_DownloadFileComplete(object sender, AsyncCompletedEventArgs e)
{
    if (e.Error == null)
    {
        MessageBox.Show("Download sucessfully!");
    }
    else
    {
        MessageBox.Show(e.Error.Message);
    }
    ((WebClient)sender).Dispose();
}

private void button1_Click(object sender, EventArgs e)
{
    int mssv = Convert.ToInt32(textBox2.Text);
    int amount = Convert.ToInt32(textBox3.Text);
    for(int i = 0; i < amount; i++)
    {
        progressBar1.Value = 0;
        WebClient wc = new WebClient();                
        wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);                    
        wc.DownloadFileAsync(new Uri("abc.com/GetImage.aspx?MSSV="+mssv), mssv.ToString()+".jpg");
        mssv++;
        if (i == amount)
        {
            wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileComplete);
        }
    }

}

1 个答案:

答案 0 :(得分:1)

这个代码块永远不会被执行,因为你的for循环条件会检查i < amount。因此i永远不会在循环内等于amount。它总是小于。

if (i == amount)
{
    wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileComplete);
}

你可以通过多种方式纠正这个......

  1. 将for循环更改为

    for(int i = 1; i <= amount; i++)
    
  2. if语句更改为

    if (i == amount-1 )
    
  3. DownloadFileCompleted事件处理程序移出循环,并重用WebClient(未经测试)。

    WebClient wc = null;
    for(int i = 0; i < amount; i++)
    {
        progressBar1.Value = 0;
        wc = new WebClient();
        wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);                        
        wc.DownloadFileAsync(new Uri("abc.com/GetImage.aspx?MSSV="+mssv), mssv.ToString()+".jpg");
        mssv++;
    }
    if( wc != null )
        wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileComplete);
    
  4. 我的个人推荐......现在,随着不同的下载报告进度,您的进度条将会遍布整个地方。 (也未经测试,我可能犯了几个拼写错误)。

    private void wc_DownloadFileComplete(object sender, AsyncCompletedEventArgs e)
    {
        progressBar1.PerformStep();
        if( e.Error != null )
        {
            string msg = String.Format("Error downloading MSSV {0}\r\n\r\n{1}",progressBar1.Value,e.Error.Message);
            MessageBox.Show(msg);
        }
        if( progressBar1.Maximum == progressBar1.Value )
        {
            MessageBox.Show("All downloads completed.");
            WebClient wc = sender as WebClient;
            if( wc != null )
                wc.Dispose();
        }
    }
    
    private void button1_Click(object sender, EventArgs e)
    {
        int mssv = Convert.ToInt32(textBox2.Text);
        int amount = Convert.ToInt32(textBox3.Text);
        progressBar1.Value = 0;
        progressBar1.Maximum = amount;
        WebClient wc = new WebClient();
        wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileComplete);
        for(int i = 0; i < amount; i++, mssv++)
        {
            Uri url = new Uri(String.Format("abc.com/GetImage.aspx?MSSV={0}",mssv));
            string path = String.Format("{0}.jpg",mssv);
            wc.DownloadFileAsync(url,path);
        }
    }
    
  5. 此外,我质疑在调用DownloadFileAsync之后添加事件处理程序的逻辑。它可能永远不会发生,但从理论上讲,对DownloadFileAsync的调用可以在添加事件处理程序之前完成。最好在调用DownloadFileAsync之前添加事件处理程序。