在WebAPI中运行时,HttpWebResponse会挂起/冻结

时间:2017-07-06 11:12:22

标签: c# asp.net-web-api

我正在使用一个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;
}

任何帮助都将不胜感激。

4 个答案:

答案 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同步。

&#13;
&#13;
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;
&#13;
&#13;