【发布时间】:2019-12-26 11:34:01
【问题描述】:
我有一个 asp.net 网络 API。 (net framework 4.6.1)我在我的一项操作中调用了第 3 方休息 API(产品)。在功能测试中,一切都按预期工作,没有问题。但是当我进行峰值测试时(比如说,100 个用户,10 秒的加速时间),在一些成功的响应之后,我得到了System.Threading.Tasks.TaskCanceledException: A task was canceled error。我用谷歌搜索并发现这可能是由于超时。我添加了TimeSpan.FromSeconds(600);,但仍然遇到同样的错误。
这就是我如何称呼这个第 3 方 API。异步调用有什么问题吗?你能看看我的代码吗?
public class UtilitiesTest
{
private static readonly HttpClient _httpClient = new HttpClient();
//some not relevant code here
public static async Task<HttpResponseMessage> CallRazer(GameRequest gameRequest, string url)
{
try
{
FormUrlEncodedContent content = null;
if (url == "Product/")
{
try
{
//some code here
//Timeout
_httpClient.Timeout = TimeSpan.FromSeconds(600);
//Call Game
var response = await _httpClient.PostAsync("https://test.com/" + url, content);
return response;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
finally
{
content.Dispose();
}
}
else
{
try
{
//some code here
//Call Game
var response = await _httpClient.PostAsync("https://test.com/" + url, content);
return response;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
finally
{
content.Dispose();
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
}
这就是我对 Razer 的称呼:
private async Task<HttpResponseMessage> CallProducts()
{
//some code here
#region Call Razer for products
//**Call Razer**
var response = await Utilities.CallRazer(products, "Product/");
var htmlResponse = await response.Content.ReadAsStringAsync();
var model = JsonConvert.DeserializeObject<ProductResponseDto>(htmlResponse);
// some code here
return response;
}
另一个论坛的某个人建议我使用 HTTPWeb 请求而不是 Httpclient。所以我像下面这样更改了我的代码,我所有的麻烦都消失了。
//HTTPWebRequest
var request = (HttpWebRequest) WebRequest.Create("http://test.com" + url);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
var keyValueContent = productRequest.ToKeyValue();
var formUrlEncodedContent = new FormUrlEncodedContent(keyValueContent);
var urlEncodedString = await formUrlEncodedContent.ReadAsStringAsync();
using (var streamWriter = new StreamWriter(await request.GetRequestStreamAsync()))
{
streamWriter.Write(urlEncodedString);
}
HttpWebResponse httpResponse = (HttpWebResponse) (await request.GetResponseAsync());
response = new HttpResponseMessage
{
StatusCode = httpResponse.StatusCode,
Content = new StreamContent(httpResponse.GetResponseStream()),
};
return response;
【问题讨论】:
-
任务取消是由于传递了取消令牌,我的理解是,如果您没有明确传递,那么取消令牌会附加在 3rd 方 API 中,这可能会由于各种逻辑原因触发任务取消。检查Task Status Enum
-
还要检查Task Cacellation,这与由于异常导致的任务错误和Cancelling Async task after Timeout不同
-
我没有传递取消令牌。当我对这种方法进行尖峰测试时会发生这种情况。起初,我得到了成功的响应,但过了一段时间我得到了错误。
-
但第 3 方 API 可能会先检查,否则任务会出现故障而不被取消
-
@MrinalKamboj 谢谢,我会检查第 3 方。顺便说一句,我的代码怎么样?有cmets吗?
标签: c# asp.net-web-api async-await dotnet-httpclient