在ASP.Net应用程序中调用异步API

编程入门 行业动态 更新时间:2024-10-07 06:44:26
本文介绍了在ASP.Net应用程序中调用异步API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我对ASP.Net和异步编码有点陌生,请耐心等待.我已经用C#为Web API编写了一个异步包装,该包装要在ASP.Net应用程序中使用.

I'm a little new to ASP.Net and Asynchronous coding so bear with me. I have written an asynchronous wrapper in C# for a web API that I would like to use in a ASP.Net application.

这是C#API包装器中的功能之一:

Here is one of the functions in the C# API wrapper:

public async Task<string> getProducts() { Products products = new Products(); products.data = new List<Item>(); string URL = client.BaseAddress + "/catalog/products"; string additionalQuery = "include=images"; HttpResponseMessage response = await client.GetAsync(URL + "?" + additionalQuery); if (response.IsSuccessStatusCode) { Products p = await response.Content.ReadAsAsync<Products>(); products.data.AddRange(p.data); while (response.IsSuccessStatusCode && p.meta.pagination.links.next != null) { response = await client.GetAsync(URL + p.meta.pagination.links.next + "&" + additionalQuery); if (response.IsSuccessStatusCode) { p = await response.Content.ReadAsAsync<Products>(); products.data.AddRange(p.data); } } } return JsonConvert.SerializeObject(products, Formatting.Indented); }

然后我的ASP.Net应用程序中有一个WebMethod(将使用Java文件中的Ajax调用它),该方法应调用getProducts()函数.

I then have a WebMethod in my ASP.Net application (which will be called using Ajax from a Javascript file) which should call the getProducts() function.

[WebMethod] public static string GetProducts() { BigCommerceAPI api = getAPI(); return await api.getProducts(); }

由于WebMethod不是异步方法,因此现在当然将不起作用.我试图将其更改为如下所示的异步方法:

Now of course this will not work as the WebMethod is not an async method. I have tried to change it to an async method which looked like:

[WebMethod] public static async Task<string> GetProducts() { BigCommerceAPI api = getAPI(); return await api.getProducts(); }

该代码确实会运行,但是一旦到达getProducts()函数中的HttpResponseMessage response = await client.GetAsync(URL + "?" + additionalQuery);行,调试器将停止运行,而不会出现任何错误或返回数据.

This code does run, but as soon as it gets to the HttpResponseMessage response = await client.GetAsync(URL + "?" + additionalQuery); line in the getProducts() function the debugger will stop without any errors or data being returned.

我想念什么?如何从ASP应用程序中调用此异步API?

What am I missing? How can I get call this asynchronous API from my ASP application?

推荐答案

所以我实际上解决了一个与昨晚非常相似的问题.奇怪的是,该调用在 4.5中有效.但是我们转到4.5.2,该方法开始出现死锁.

So I actually resolved an issue very similar to this last night. It's odd because the call worked in 4.5. But we moved to 4.5.2 and the method started deadlocking.

我找到了这些启发性的文章(此处,此处和此处).

I found these enlightening articles (here, here, and here) on async and asp.

所以我修改了代码

public async Task<Member> GetMemberByOrganizationId(string organizationId) { var task = await // ReSharper disable once UseStringInterpolation _httpClient.GetAsync(string.Format("mdm/rest/api/members/member?accountId={0}", organizationId)).ConfigureAwait(false); task.EnsureSuccessStatusCode(); var payload = task.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<Member>(await payload.ConfigureAwait(false), new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }); }

这解决了我的僵局问题.

which resolved my deadlocking issue.

所以TLDR:来自Stephen Cleary的文章

So TLDR: from the Stephen Cleary article

在概述中,我提到当您等待内置等待时, 然后等待的对象将捕获当前的上下文",然后再应用 它到异步方法的其余部分.那到底是什么 上下文"?

In the overview, I mentioned that when you await a built-in awaitable, then the awaitable will capture the current "context" and later apply it to the remainder of the async method. What exactly is that "context"?

简单答案:

如果您使用的是UI线程,则它是一个UI上下文.如果您正在回应 到一个ASP.NET请求,那么它就是一个ASP.NET请求上下文. 否则,通常是线程池上下文.复杂的答案:

If you’re on a UI thread, then it’s a UI context. If you’re responding to an ASP.NET request, then it’s an ASP.NET request context. Otherwise, it’s usually a thread pool context. Complex answer:

如果SynchronizationContext.Current不为null,则为当前 SynchronizationContext. (UI和ASP.NET请求上下文是 SynchronizationContext上下文).否则,这是当前的 TaskScheduler(TaskScheduler.默认为线程池上下文).

If SynchronizationContext.Current is not null, then it’s the current SynchronizationContext. (UI and ASP.NET request contexts are SynchronizationContext contexts). Otherwise, it’s the current TaskScheduler (TaskScheduler.Default is the thread pool context).

和解决方案

在这种情况下,您想告诉等待者不要捕获当前的 通过调用ConfigureAwait并传递false来获取上下文

In this case, you want to tell the awaiter to not capture the current context by calling ConfigureAwait and passing false

更多推荐

在ASP.Net应用程序中调用异步API

本文发布于:2023-11-28 06:15:55,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1641256.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:应用程序   ASP   Net   API

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!