我正在使用一个C#WebAPI项目,该项目将根据其URL调用外部API。但是,当我尝试检索数据时,它会挂起/冻结。
停止的代码是:
var response = (HttpWebResponse)await Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
我不明白为什么它会停止。它是否会干扰我正在制作的API请求?当我将此代码作为单元测试的一部分运行时,我会在几秒钟内得到响应。我不认为这是API服务本身,我认为这是我的代码。我已经尝试了各种API URL。他们都没有工作。
我的完整代码是:
public static async Task<string> CallWebAPi<T>(string url)
{
string returnValue;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.ContentType = "application/json";
request.Method = "GET";
var response = (HttpWebResponse)await Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
Stream stream = response.GetResponseStream();
StreamReader strReader = new StreamReader(stream);
returnValue = await strReader.ReadToEndAsync();
return returnValue;
}
任何帮助都将不胜感激。
答案 0 :(得分:1)
可能死锁ConfigureAwait(false),这是斯蒂芬关于deadlocks的原因的一个很好的解释。
var response = (HttpWebResponse)await Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null).ConfigureAwait(false);
答案 1 :(得分:0)
作为一种解决方法,您可以使用同步功能,创建任务并等待此任务:
var response = await Task.Run(() =>
{
return (HttpWebResponse)request.GetResponse();
});
答案 2 :(得分:0)
你不需要Task.Factory.FromAsync。 HttpWebRequest已经支持异步操作。
您已定义了通用方法CalWebApi<T>
,但从未使用过通用类型
如果您的操作是异步,请使用此选项。
public async Task<T> CalWebApiAsync<T>(string url)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.ContentType = "application/json";
request.Method = "GET";
using (var response = await request.GetResponseAsync())
{
using (var responseStream = response.GetResponseStream())
{
using (var streamReader = new StreamReader(responseStream))
{
var stringResult = await streamReader.ReadToEndAsync();
T objectResult = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(stringResult);
return objectResult;
}
}
}
}
var result = await CallWebApiAsync<YourType>("exteranlapiurl");
如果您的操作不是异步,请使用此..
public T CalWebApi<T>(string url)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.ContentType = "application/json";
request.Method = "GET";
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
using (var streamReader = new StreamReader(responseStream))
{
var stringResult = streamReader.ReadToEnd();
T objectResult = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(stringResult);
return objectResult;
}
}
}
}
var result = CallWebApi<YourType>("exteranlapiurl");
答案 3 :(得分:0)
这就是我的要求。每个部分都有自己的功能。它创建了Request,你可以让Response同步。
public HttpWebRequest CreateRequest(string Url, string Method, string ContentType, object Content, List<RequestHeader> headers)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
request.Method = Method;
if (!string.IsNullOrWhiteSpace(ContentType)) request.ContentType = ContentType;
else if(Content != null) request.ContentType = "application/json";
if (Content != null)
{
var postData = Newtonsoft.Json.JsonConvert.SerializeObject(Content);
var data = Encoding.ASCII.GetBytes(postData);
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
}
foreach(RequestHeader header in Headers)
{
request.Headers.Add(header.Type, header.Value);
} //class at the end.
return request;
}
public string GetResponse(HttpWebRequest request)
{
var retval = "";
try
{
var response = (HttpWebResponse)request.GetResponse();
retval = ReadResponse(response);
response.Close();
}
catch (Exception ex)
{
resolveException(ex.Message);
}
return retval;
}
public string ReadResponse(HttpWebResponse response)
{
var retval = "";
try
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
var responseText = reader.ReadToEnd();
retval = responseText;
}
}
catch (Exception ex)
{
resolveException(ex.Message);
}
return retval;
}
public class RequestHeader
{
public HttpRequestHeader Type { get; set; }
public string Value { get; set; }
}
&#13;