使用 async/await 并从 ASP.NET Web API 方法返回 Task<HttpResponseMessage>

Posted

技术标签:

【中文标题】使用 async/await 并从 ASP.NET Web API 方法返回 Task<HttpResponseMessage>【英文标题】:Using async/await and returning Task<HttpResponseMessage> From ASP.NET Web API Methods 【发布时间】:2012-12-13 15:50:34 【问题描述】:

我有一个像这样的可移植类库 (PCL) 方法:

public async Task<string> GetLineStatuses()

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
    using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
    
        return response.GetResponseStream().ReadAllText();
    

我的 ASP.NET Web Api 方法如下所示:

public async Task<HttpResponseMessage> Get()

    HttpResponseMessage response = new HttpResponseMessage();
    string statuses = await service.GetStatuses();
    response.Content = new StringContent(statuses);
    return response;

在 Web API 中返回任务的含义是什么。这是允许的吗?我想使用 await 的唯一原因是我可以使用可移植类库 (PCL)。最佳做法是什么?我应该有我的方法的同步版本和异步版本吗?对性能和代码可读性和可维护性有何影响?

如果我返回Task&lt;string&gt;而不是Task&lt;HttpResponseMessage&gt;,我也会有同样的效果吗?

【问题讨论】:

我相信 .Net 4.5 中的 ASP.NET 确实支持 async 方法,因此您的代码应该可以正常工作。你为什么要问这是否允许?你没试过吗? 我也想知道性能和代码可读性和可维护性的影响? 【参考方案1】:

Async 和 await 在 ASP.NET 中是完全可以接受的。这是 Scott Handselman 的演示视频:http://www.asp.net/vnext/overview/aspnet/async-and-await

“如果我返回Task&lt;string&gt;而不是Task&lt;HttpResponseMessage&gt;,我也会有同样的效果吗?”

不太清楚你的意思。 Task 就像对象的容器,因此 Task&lt;string&gt; 将包含您的字符串结果,而 Task&lt;HttpResponseMessage&gt; 将包含您的 HttpResponseMessage 结果...这是您的意思吗?我认为这两种方法都是完全可以接受的。如果你只需要字符串,那就去吧。超过你需要的回报是没有意义的。

【讨论】:

在 Web API 中,您可以返回任何您想作为内容序列化的对象或返回一个 HttpResponseMessage。这就是我的意思。 我还没关注你。请记住,它不是返回一个字符串,而是一个 Task。 Task.Result 中的字符串可以呈现为内容,但 Task 本身不能。 返回一个字符串并返回一个带有 StringContent 的 HttpResponseMessage 和两个不同的东西。如果您返回一个字符串,WebAPi 将使用内容协商来查找可以序列化该字符串的格式化程序。如果您返回 StringContent,则该字符串会直接在响应中输出。但是就 WebAPI 而言,返回最终以字符串完成的 Task 应该等同于直接返回该字符串。【参考方案2】:

作为替代:

public static async Task<string> CallGET(string requestUri, string id = "")

    string responseData;
    using (var client = new HttpClient(new HttpClientHandler()  UseDefaultCredentials = true ))
    
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        Uri.TryCreate(new Uri(baseURI), $"requestUri(string.IsNullOrEmpty(id) ? string.Empty : $"/id")", out Uri fullRequestUri);
        using (var response = await client.GetAsync(fullRequestUri))
        
            responseData = await response.Content.ReadAsStringAsync();
        
        return responseData;
    

然后调用是:

var getListUsersResult = Utils.CallGET($"/v1/users").Result;
var resultset= JsonConvert.DeserializeObject(getListUsersResult, typeof(List<UsersDTO>)) as List<UsersDTO>;
UserDTO r = users.Where(d => d.Name.ToLower().Contains("test")).FirstOrDefault();

又一次要求一件物品:

var getUser = Utils.CallGET($"/v1/users", $"USER_ID").Result;
var getUserResponse = JsonConvert.DeserializeObject(getUser, typeof(UserDTO)) as UserDTO;

【讨论】:

以上是关于使用 async/await 并从 ASP.NET Web API 方法返回 Task<HttpResponseMessage>的主要内容,如果未能解决你的问题,请参考以下文章

async / await 如何在 ASP.Net 应用程序中提供帮助?

asp.net webform中使用async,await实现异步操作

asp.net webform中使用async,await实现异步操作

如何在 ASP.NET Web API 中使用非线程安全的 async/await API 和模式?

深入理解 ASP.NET MVC 上的 async/await

为啥总是在 asp.net mvc 中同步异步操作(async await)