4

我正在尝试使用三个单独的 WebClient 下载三个文件。我用这个:

    void client1_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        MessageBox.Show("CLIENT1");
    }

    void client2_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        MessageBox.Show("CLIENT2");
    }

    void client3_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        MessageBox.Show("CLIENT3");
    }

    private void mwindow_Loaded(object sender, RoutedEventArgs e)
    {
        string rand = new Random().Next().ToString();
        WebClient client1 = new WebClient();
        client1.OpenReadCompleted += client1_OpenReadCompleted;
        client1.OpenReadAsync(new Uri("http://www.example.com/file.exe?r=" + rand));

        WebClient client2 = new WebClient();
        client2.OpenReadCompleted += client2_OpenReadCompleted;
        client2.OpenReadAsync(new Uri("http://www.example.com/file.exe?r=" + rand));

        WebClient client3 = new WebClient();
        client3.OpenReadCompleted += client3_OpenReadCompleted;
        client3.OpenReadAsync(new Uri("http://www.example.com/file.exe?r=" + rand));
    }

使用它时,无论我做什么,三个 WebClient 中只有两个会完成。使用此代码,我得到两个消息框“CLIENT1”和“CLIENT2”,但“CLIENT3”从未出现。不会抛出异常或任何东西。什么都没发生。如果我颠倒 WebClients 的顺序,client3并且client2工作但不是client1. 我尝试更改代码以使 WebClients 一次下载一个而不是异步:

        WebClient client1 = new WebClient();
        Stream str1 = client1.OpenRead(new Uri("http://www.example.com/file.exe?r=" + rand));
        MessageBox.Show("CLIENT1");

        WebClient client2 = new WebClient();
        Stream str2 = client2.OpenRead(new Uri("http://www.example.com/file.exe?r=" + rand));
        MessageBox.Show("CLIENT2");

        WebClient client3 = new WebClient();
        Stream str3 = client3.OpenRead(new Uri("http://www.example.com/file.exe?r=" + rand));
        MessageBox.Show("CLIENT3");

但是,程序冻结就Stream str3 = client3.OpenRead(new Uri("http://www.example.com/file.exe?r=" + rand));行了。同步client1下载所有文件而不是创建多个 WebClient 也会冻结第三个文件。

4

1 回答 1

5

我认为您遇到的是两个问题的结合。第一个是并发WebRequest连接数默认限制为2。您可以通过创建一个派生自WebClient并覆盖该GetWebRequest方法的类来更改它,如下所示:

public class ExtendedWebClient : WebClient
{
    /// <summary>
    /// Gets or sets the maximum number of concurrent connections (default is 2).
    /// </summary>
    public int ConnectionLimit { get; set; }

    /// <summary>
    /// Creates a new instance of ExtendedWebClient.
    /// </summary>
    public ExtendedWebClient()
    {
        this.ConnectionLimit = 2;
    }

    /// <summary>
    /// Creates the request for this client and sets connection defaults.
    /// </summary>
    protected override WebRequest GetWebRequest(Uri address)
    {
        var request = base.GetWebRequest(address) as HttpWebRequest;

        if (request != null)
        {
            request.ServicePoint.ConnectionLimit = this.ConnectionLimit;
        }

        return request;
    }
}

我看到的第二个问题是,Stream当您调用 时,您没有关闭/处理返回的内容OpenRead,因此这两个请求似乎直到垃圾收集器决定为您启动并关闭这些流时才完成。

于 2013-06-16T02:38:37.777 回答