C#HttpWebRequest-停止等待响应
我正在向外部服务器发出HEAD请求,以确定我的凭据是否有效。但是,外部服务器(我无法控制)正在处理我的请求,就好像它是GET一样(并开始生成CSV到流,这可能需要30分钟才能生成) 如果我的证件不正确,我会立即取回401。如果请求需要很长时间(超过10秒),我知道我的凭据是正确的b/c外部服务器已开始生成CSV 我希望我的请求在10秒后超时。但是我在HttpWebRequest.Timeout和HttpWebRequest.ReadWriteTimeout方面遇到了问题。。。这些值似乎没有得到确认&我的请求似乎将永远等待完整的响应 我如何让超时真正发生 以下是我得到的:C#HttpWebRequest-停止等待响应,c#,asp.net,C#,Asp.net,我正在向外部服务器发出HEAD请求,以确定我的凭据是否有效。但是,外部服务器(我无法控制)正在处理我的请求,就好像它是GET一样(并开始生成CSV到流,这可能需要30分钟才能生成) 如果我的证件不正确,我会立即取回401。如果请求需要很长时间(超过10秒),我知道我的凭据是正确的b/c外部服务器已开始生成CSV 我希望我的请求在10秒后超时。但是我在HttpWebRequest.Timeout和HttpWebRequest.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;
}
}
公共异步任务GetResponse(字符串url、字符串用户名、字符串机密)
{
HttpWebRequest _request=新的HttpWebRequest(url);
NetworkCredential _credential=新的NetworkCredential(用户名、密码);
CredentialCache _CredentialCache=新的CredentialCache{{url,“Basic”,_credential};
_request.PreAuthenticate=true;
_request.Credentials=\u credentialCache;
//我在测试时设置了所有3个超时,但似乎没有一个被确认。
_request.ContinueTimeout=10000;
_request.ReadWriteTimeout=10000;
_请求超时=10000;
尝试
{
使用(HttpWebResponse\u response=wait\u request.GetResponseAsync())
{
if(_response.StatusCode==HttpStatusCode.OK&&u response.ContentType.Contains(“text/csv”)
{
return true;//成功检索到响应。
}
return false;//检索成功响应失败。
}
}
捕获(WebException ex)
{
if(ex.Status=WebExceptionStatus.Timeout)
{
返回true;//超时==成功。
}
返回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;
}
}
}
公共密封类MyClass:IMyClass
{
私有静态只读HttpClient _HttpClient=新HttpClient();
公共异步任务MyMethod(字符串url、字符串用户名、字符串机密)
{
尝试
{
CancellationTokenSource _cts=新的CancellationTokenSource(Timespan.FromSeconds(10));
_httpClient.DefaultRequestHeaders.Authorization=new AuthenticationHeaderValue(
“基本”,
Convert.ToBase64String(Encoding.UTF8.GetBytes($“{username}:{secret}”));
HttpResponseMessage\u response=wait\u httpClient.SendAsync(
新的HttpRequestMessage(HttpMethod.Head,model.ApiUrl),
HttpCompletionOption.ResponseHeadersRead,
_cts.Token);
开关(_response.StatusCode)
{
案例HttpStatusCode.OK:
返回true;
违约:
返回false;
}
}
捕获(TaskCanceledException)
{
返回true;
}
}
}
这个答案应该会有帮助:另外,我可以建议HttpClient
——这是一种更干净/更现代的方法