Web page downloader that supports redirects
HttpClient and associated classes provide most of the desired behavior.

HttpClientHandler already has the ability to follow redirection responses out of the box with AllowAutoRedirect property. You can also specify how many redirections to allow.

That can be extracted out into a function

static HttpMessageHandler CreateHandler() {
    var handler = new HttpClientHandler();
    // if the framework supports redirect configuration
    // set max redirect to the desired amount. The default is 50
    if (handler.SupportsRedirectConfiguration) {
        handler.AllowAutoRedirect = true;
        handler.MaxAutomaticRedirections = 5;
    }
    // if the framework supports automatic decompression 
    // set automatic decompression
    if (handler.SupportsAutomaticDecompression) {
        handler.AutomaticDecompression = System.Net.DecompressionMethods.GZip |
            System.Net.DecompressionMethods.Deflate;
    }
    return handler;
}


Creating multiple instances of HttpClient can cause an exhaustion of available sockets, so it is suggested to try keeping one instance for the duration of the application. 

Specify a short time out duration for slower responses to help with time management. 

static Lazy&lt;HttpClient&gt; httpClient = new Lazy&lt;HttpClient&gt;(() =&gt; {
    var handler = CreateHandler();
    return new HttpClient(handler) {
        Timeout = TimeSpan.FromSeconds(3)
    };
});


Timeout can be adjusted to specific needs.

Cancellation tokens can also be used to help with time management.

Seeing as any exception is just being rethrown, then there is really no need for the try/catch. The exception would be handled by the caller.

HttpClient uses an asynchronous API. Its dependents should also be asynchronous all the way through and avoid blocking calls like .Result or .Wait to avoid deadlocks.

The refactored helper now looks like this

/// &lt;summary&gt;
/// Download html from an Internet page.
/// &lt;/summary&gt;
public class NetworkHelper {
    static Lazy&lt;HttpClient&gt; httpClient = new Lazy&lt;HttpClient&gt;(() =&gt; {
        var handler = CreateHandler();
        return new HttpClient(handler) {
            Timeout = TimeSpan.FromSeconds(3)
        };
    });

    static HttpMessageHandler CreateHandler() {
        var handler = new HttpClientHandler();
        // if the framework supports redirect configuration
        // set max redirect to the desired amount the default is 50
        if (handler.SupportsRedirectConfiguration) {
            handler.AllowAutoRedirect = true;
            handler.MaxAutomaticRedirections = 5;
        }
        // if the framework supports automatic decompression 
        // set automatic decompression
        if (handler.SupportsAutomaticDecompression) {
            handler.AutomaticDecompression = System.Net.DecompressionMethods.GZip |
                System.Net.DecompressionMethods.Deflate;
        }
        return handler;
    }

    /// &lt;summary&gt;
    /// Get the html structure of a site.
    /// &lt;/summary&gt;
    /// &lt;param name="url"&gt;Represents the URL of the page where to download the data.&lt;/param&gt;
    /// &lt;returns&gt;Return a string that contains the html of the site.&lt;/returns&gt;
    public async Task&lt;string&gt; GetHtmlAsync(Uri url, CancellationToken cancellationToken = default(CancellationToken)) {
        var response = await httpClient.Value.GetAsync(url, cancellationToken);
        var content = await response.Content.ReadAsStringAsync();
        return content;
    }
}


And used

//...

var client = new NetworkHelper();
var html = await clien.GetHtmlAsync(uri);