即使我增加超时,我也会得到TaskCanceledException
。令人惊讶的是它甚至不会一直发生,异常仅在某个时间发生,我无法找到模式来重现错误。我添加了用于进行网络呼叫的异常跟踪和代码。
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。
可以帮助我解决这个问题。我在互联网上搜索并增加超时但没有用。
答案 0 :(得分:2)
我希望有些评论可以帮助您解决问题:
async
方法应返回Task
,而不是void
。您不必实际返回Task
对象,编译器将处理此问题。唯一的例外是WinForms和WebForms事件处理程序。getResponseFromUrlAsync
方法不是异步,但它应该是。您应该添加async
修饰符,然后返回Task
。然后,await makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction(...)
。这可能是您的问题的根源 - 在返回之前,您没有等待异步操作完成。httpClient
变量是全局定义的。您可以轻松地遇到NullReferenceException,因为即使不先调用makeNetworkCallCheckResponseStatusAndExecuteCorrospondingAction
也可以调用getResponseFromUrlAsync
,disposeConnection
也可以调用httpClient
。如果您的类始终使用DatetimeIndex
,请在构造函数或声明中初始化它。如果不是,请检查方法开头是否为空。答案 1 :(得分:1)
您应该等待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<..>(...);