4

3 つの個別の WebClient で 3 つのファイルをダウンロードしようとしています。私はこれを使用します:

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

これを使用すると、何をしても、3 つの WebClient のうち 2 つだけが終了します。このコードを使用すると、"CLIENT1" と "CLIENT2" という 2 つのメッセージ ボックスが表示されますが、"CLIENT3" は表示されません。例外はスローされません。何も起こりません。WebClients の順序を逆にすると、動作しますがclient3client2動作しませんclient1。コードを変更して、非同期ではなく WebClient を一度に 1 つずつダウンロードしようとしました。

        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));行でフリーズします。複数の WebClientをclient1作成する代わりにすべてのファイルを同期的にダウンロードすると、3 番目のファイルでもフリーズします。

4

1 に答える 1

5

あなたが経験しているのは、2 つの問題の組み合わせだと思います。1 つ目は、同時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;
    }
}

私が目にする 2 番目の問題は、Stream呼び出し時に返されたOpenReadものを閉じたり破棄したりしていないことです。そのため、ガベージ コレクターがこれらのストリームを起動して閉じることを決定するまで、2 つの要求が完了しないように見えます。

于 2013-06-16T02:38:37.777 に答える