HttpClient c# - SendASync中取消任务
即使增加超时,我也得到TaskCanceledException
。令人惊讶的是,它甚至不会总是发生,异常只发生在某个时间,我无法找到重现错误的模式。我添加了用于进行网络调用的异常跟踪和代码。HttpClient c# - SendASync中取消任务
public static void getResponseFromUrlAsync<T>(T payload, string url,
Action<string> onSuccess, Action<string> onFailure)
{
string contentType = "application/json";
httpClient = new HttpClient();
httpClient.Timeout = TimeSpan.FromMinutes(30);
HttpRequestMessage requestMsg = new HttpRequestMessage();
requestMsg.RequestUri = new Uri(NetworkCallUrls.baseUri + url);
Utils.debugLog("Url", NetworkCallUrls.baseUri + url);
// try
//{
string auth = "Bearer " + Objects.GlobalVars.GetValue<string>("access_token"); // //"x1VwaR1otS66ZCTlgtv3X9aaSNpDOn"; //
httpClient.DefaultRequestHeaders.Add("Authorization", auth);
requestMsg.Method = HttpMethod.Post;
requestMsg.Content = new StringContent(
Utils.stringifyData(payload),
Encoding.UTF8,
contentType);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));//ACCEPT header
makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction(requestMsg, onSuccess, onFailure, progressBarStatus);
}
internal static void disposeConnection(HttpClient httpClient)
{
httpClient.Dispose();
httpClient = null;
}
private static async void makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction(
HttpRequestMessage requestMsg, Action<string> onSuccess,
Action<string> onFailure, Action<bool> progressBarStatus)
{
Utils.debugLog("IN MAKE NETWORK CALL 1");
HttpResponseMessage response = await httpClient.SendAsync(requestMsg);
Utils.debugLog("IN MAKE NETWORK CALL 2");
ResponseStatus responseStatus = checkResponseStatusAndExecuteActionAccordinglyAsync(response);
Utils.debugLog("IN MAKE NETWORK CALL 3");
if (responseStatus.isSuccess)
{
Utils.debugLog("IN MAKE NETWORK CALL 4");
string responseString = await response.Content.ReadAsStringAsync();
Utils.debugLog("IN MAKE NETWORK CALL 5");
onSuccess(responseString);
Utils.debugLog("IN MAKE NETWORK CALL 6");
}
else
{
Utils.debugLog("IN MAKE NETWORK CALL 7");
onFailure(responseStatus.failureResponse);
Utils.debugLog("IN MAKE NETWORK CALL 8");
}
Utils.debugLog("IN MAKE NETWORK CALL 9");
disposeConnection(httpClient);
Utils.debugLog("IN MAKE NETWORK CALL 10");
}
我使用上面的代码进行API调用,我在HttpResponseMessage response = await httpClient.SendAsync(requestMsg);
线越来越TaskCanceledException。
有人可以帮我解决这个问题。我在网上搜索并增加超时,但没用。
您应该等待makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction
方法和getResponseFromUrlAsync
方法。这意味着你需要返回类型更改从void
到Task
:
public static async Task getResponseFromUrlAsync<T>(T payload, string url, Action<string> onSuccess, Action<string> onFailure)
{
string contentType = "application/json";
httpClient = new HttpClient();
httpClient.Timeout = TimeSpan.FromMinutes(30);
HttpRequestMessage requestMsg = new HttpRequestMessage();
requestMsg.RequestUri = new Uri(NetworkCallUrls.baseUri + url);
Utils.debugLog("Url", NetworkCallUrls.baseUri + url);
string auth = "Bearer " + Objects.GlobalVars.GetValue<string>("access_token"); // //"x1VwaR1otS66ZCTlgtv3X9aaSNpDOn"; //
httpClient.DefaultRequestHeaders.Add("Authorization", auth);
requestMsg.Method = HttpMethod.Post;
requestMsg.Content = new StringContent(
Utils.stringifyData(payload),
Encoding.UTF8,
contentType);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));//ACCEPT header
await makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction(requestMsg, onSuccess, onFailure, progressBarStatus)
.ConfigureAwait(false);
}
internal static void disposeConnection(HttpClient httpClient)
{
httpClient.Dispose();
httpClient = null;
}
private static async Task makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction(
HttpRequestMessage requestMsg, Action<string> onSuccess,
Action<string> onFailure, Action<bool> progressBarStatus)
{
Utils.debugLog("IN MAKE NETWORK CALL 1");
HttpResponseMessage response = await httpClient.SendAsync(requestMsg).ConfigureAwait(false);
Utils.debugLog("IN MAKE NETWORK CALL 2");
ResponseStatus responseStatus = checkResponseStatusAndExecuteActionAccordinglyAsync(response);
Utils.debugLog("IN MAKE NETWORK CALL 3");
if (responseStatus.isSuccess)
{
Utils.debugLog("IN MAKE NETWORK CALL 4");
string responseString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
Utils.debugLog("IN MAKE NETWORK CALL 5");
onSuccess(responseString);
Utils.debugLog("IN MAKE NETWORK CALL 6");
}
else
{
Utils.debugLog("IN MAKE NETWORK CALL 7");
onFailure(responseStatus.failureResponse);
Utils.debugLog("IN MAKE NETWORK CALL 8");
}
Utils.debugLog("IN MAKE NETWORK CALL 9");
disposeConnection(httpClient);
Utils.debugLog("IN MAKE NETWORK CALL 10");
}
...和await
方法时,你把它叫做:
await getResponseFromUrlAsync<..>(...);
,我希望能帮助您解决问题的一些意见:
-
async
方法应该返回Task
如果你没有返回,不void
。你不必实际返回一个Task
对象,编译器会处理这个。唯一的例外是WinForms和WebForms事件处理程序。 - 您的
getResponseFromUrlAsync
方法不是异步的,但它应该是。您应该添加一个async
修饰符,并返回Task
。然后,await makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction(...)
。这可能是问题的根源 - 在返回之前,您并未等待异步操作完成。 - 在一般说明中,似乎您的
httpClient
变量是在全局某个地方定义的。你可以很容易地遇到一个NullReferenceException,因为makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction
甚至可以不用先调用getResponseFromUrlAsync
,disposeConnection
也可以调用。如果您的课程始终使用httpClient
,请在构造函数或声明中对其进行初始化。如果不是,请在方法开始时检查它是否为空。
对于2日,我在“makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction”等待所以我想我不需要等待和异步和任务返回'getResponseFromUrlAsync' – djkp
@djkp,你这样做。 'makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction'是异步的,如果你不等待它,你会在它执行完成之前返回。一旦你开始使用异步,它一直是异步编程的根。 –
我认为对于我来说,问题是在api call_1完成之前,httpClient已更新为新的,因为我正在多次调用一个接一个,没有任何延迟,所以在返回上一个调用之前,我正在拨打另一个电话 – djkp
但是,将根据最佳实践更新代码,谢谢:) – djkp
这就是为什么你应该等待的方法。 – mm8