繁体   English   中英

C# HttpWebRequest - 停止等待响应

[英]C# HttpWebRequest - Stop waiting for response

我正在向外部服务器发出 HEAD 请求,以确定我的凭据是否有效。 但是,外部服务器(我无法控制)正在处理我的请求,就好像它是 GET(并开始生成 CSV 到 stream,最多可能需要 30 分钟才能生成。)

如果我的凭据不正确,我会立即返回 401。如果请求需要很长时间(超过 10 秒),我知道我的凭据是正确的,因为外部服务器已开始生成 CSV。

我希望我的请求在 10 秒后超时。 但是我遇到了HttpWebRequest.TimeoutHttpWebRequest.ReadWriteTimeout的问题......这些值似乎没有得到确认,我的请求似乎会永远等待完整的响应。

我如何让超时真正发生?

这是我得到的:

public async Task<bool> GetResponse(string url, string username, string secret)
{
    HttpWebRequest _request = new HttpWebRequest(url);
    NetworkCredential _credential = new NetworkCredential(username, secret);
    CredentialCache _credentialCache = new CredentialCache { { url, "Basic", _credential } };
    _request.PreAuthenticate = true;
    _request.Credentials = _credentialCache;

    // I set all 3 of these timeouts while testing but none of them seem to be acknowledged.
    _request.ContinueTimeout = 10000;
    _request.ReadWriteTimeout = 10000;
    _request.Timeout = 10000;

    try
    {
        using (HttpWebResponse _response = await _request.GetResponseAsync())
        {
            if (_response.StatusCode == HttpStatusCode.OK && _response.ContentType.Contains("text/csv")
            {
                return true; // successfully retrieved response.
            }

            return false; // failed to retrieve successful response.
        }
    }
    catch (WebException ex)
    {
        if (ex.Status = WebExceptionStatus.Timeout)
        {
            return true; // timeout == success.
        }

        return false;
    }
}

我花了太长时间才弄清楚... HttpWebRequest.GetResponseAsync()不确认超时。 但是HttpWebRequest.GetResponse()可以。 您必须使用同步版本。

另外,我只需要设置超时,而不是 ReadWriteTimeout 或 ContinueTimeout。

编辑

我最终决定使用 HttpClient 而不是 HttpWebRequest。 这是它的样子:

public sealed class MyClass : IMyClass
{
    private static readonly HttpClient _httpClient = new HttpClient();

    public async Task<bool> MyMethod(string url, string username, string secret)
    {
        try
        {
            CancellationTokenSource _cts = new CancellationTokenSource(Timespan.FromSeconds(10));
           _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
                "Basic",
                Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{secret}")))); 
            HttpResponseMessage _response = await _httpClient.SendAsync(
                new HttpRequestMessage(HttpMethod.Head, model.ApiUrl),
                HttpCompletionOption.ResponseHeadersRead,
                _cts.Token);

            switch (_response.StatusCode)
            {
                case HttpStatusCode.OK:
                    return true;
                default:
                    return false;
            }
        }
        catch (TaskCanceledException)
        {
            return true;
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM