【问题标题】:WebClient multi file Downloader errorWebClient多文件下载器错误
【发布时间】:2011-10-06 14:34:40
【问题描述】:

我使用以下代码从我的网络服务器下载 50 多个文件

private void button5_Click(object sender, EventArgs e)
{

WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);

//downloads
client.DownloadFileAsync(new Uri("http://www.site.com/file/loc.file"), @"c:\app\loc ");
client.DownloadFileAsync(new Uri("http://www.site.com/file/loc.file"), @"c:\app\loc ");
client.DownloadFileAsync(new Uri("http://www.site.com/file/loc.file"), @"c:\app\loc ");
 }

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

    private void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
    {
        MessageBox.Show("Game Update Finished!");
    }

我想一次下载 1 个文件并带有一个持续的进度条 iv 完成了大部分编码,但是当我点击“下载”按钮时,我收到以下错误

WebClient 不支持并发 I/O 操作。

我需要做什么?

【问题讨论】:

  • 只是你试图写入同一个文件

标签: c# windows winforms .net-4.0


【解决方案1】:

感受不同:

  • 它可以并行下载多个文件(每个文件一个流 一个文件)。
  • 但它无法使用多个流下载一个文件。

这里是示例(MainWindow 包含一个“开始”按钮和五个进度条):

public partial class MainWindow : Window
{
    private WebClient _webClient;
    private ProgressBar[] _progressBars;
    private int _index = 0;

    public MainWindow()
    {
        InitializeComponent();
        _progressBars = new [] {progressBar1, progressBar2, progressBar3, progressBar4, progressBar5};
        ServicePointManager.DefaultConnectionLimit = 5;
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        Interlocked.Increment(ref _index);
        if (_index > _progressBars.Length)
            return;

        _webClient = new WebClient();
        _webClient.DownloadProgressChanged += WebClient_DownloadProgressChanged;
        _webClient.DownloadFileCompleted += WebClient_DownloadFileCompleted;

        _webClient.DownloadFileAsync(new Uri("http://download.thinkbroadband.com/5MB.zip"),
                                     System.IO.Path.GetTempFileName(),
                                     _index);
    }

    private void WebClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs args)
    {
        var index = (int) args.UserState;
        _progressBars[index-1].Value = args.ProgressPercentage;
    }

    private void WebClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs args)
    {
        var index = (int)args.UserState;

        MessageBox.Show(args.Error == null
                            ? string.Format("Download #{0} completed!", index)
                            : string.Format("Download #{0} error!\n\n{1}", index, args.Error));
    }
}

【讨论】:

  • 这里的 ServicePointManager 是什么@White。你能告诉我ServicePointManager的用法或给出完整的代码吗?谢谢
  • @Thomas 我使用它的静态属性msdn.microsoft.com/en-us/library/… 来限制连接数
【解决方案2】:

您正在使用同一个 WebClient 实例并行运行多个下载 - 错误告诉您不支持此操作 - 您也可以:

  • 使用WebClient 的多个实例(每个并行下载一个) 或
  • 一个接一个地下载文件

相关信息:

【讨论】:

    【解决方案3】:

    WebClient 不支持每个实例的并发 I/O 操作(多次下载),因此您需要为每个下载创建单独的 WebClient 实例。您仍然可以异步执行每次下载并使用相同的事件处理程序。

    【讨论】:

    • 通过使用相同的事件处理程序,我的意思是您可以将所有实例事件汇集到一个方法中,但是您必须修改逻辑以聚合数据,因为事件处理程序方法将从不同的实例。
    猜你喜欢
    • 2017-03-09
    • 2012-09-08
    • 1970-01-01
    • 2015-12-30
    • 2017-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-28
    相关资源
    最近更新 更多