提问人:dotnetpleb 提问时间:9/15/2023 最后编辑:dotnetpleb 更新时间:9/16/2023 访问量:24
来自基控制器的异步方法调用 - 旧的 .net 项目
Asynchronous method calls from base controller - old .net project
问:
我继承了一个 .net 4.6.2 MVC 项目,该项目通过从基本控制器中进行 API 调用来填充 basecontroller 的 viewbag。在basecontroller发出api请求之前,我需要确保我有一个有效的访问令牌来执行此操作。
由于基本控制器返回 void,我在等待调用以确保我获得有效的访问令牌时遇到了一些问题,并且出现错误。
我有点卡在如何继续上,在这种情况下,任何人都可以为我提供有关如何解决此问题的建议,或者也许是一个合理的重构,仍然可以实现我的目标,即不仅在我的控制器中,而且在基本控制器中拥有有效的访问令牌。an asynchronous module or handler completed while an asynchronous operation was still pending.
我尝试了以下方法:
var accessTokenProvider = new AccessTokenProvider();
var task = accessTokenProvider.AcquireAccessTokenAsync(filterContext)
.ConfigureAwait(false)
.GetAwaiter();
task.GetResult();
但这会导致初始加载时间非常长 - 有时会抛出 500 - 请求超时。 Web 服务器未能在指定时间内响应。
答:
这会导致非常长的初始加载时间 - 有时会抛出 500 - 请求超时。Web 服务器未能在指定时间内响应。
这可能是由于在 ASP.NET pre-Core 应用程序中阻塞异步代码所致。链接是我的博客,我在其中详细解释了僵局。
由于基本控制器返回 void,我在等待调用以确保我获得有效的访问令牌时遇到了一些问题,并且出现错误。
an asynchronous module or handler completed while an asynchronous operation was still pending.
这是一个“安全网”异常,意味着代码不正确。在这种情况下,它可能使用了异步 void
,这是一个禁忌。
在这种情况下,任何人都可以就如何解决这个问题向我提供建议,或者进行合理的重构,以仍然实现我的目标,即不仅在我的控制器中而且在基本控制器中都拥有有效的访问令牌。
你最好的选择是一路异步。您可能在基本控制器中有一个新方法来获取访问令牌;make 该方法,而不是 并确保在调用 API 之前进行 ed。async Task
async void
Task
await
另一种选择是使所有代码同步。理想情况下,您应该拥有(或编写)一个完全同步工作的方法(即,不阻塞异步代码,这可能会导致死锁)。如果完全同步,则基本控制器在可伸缩性方面不会非常高效,但在准备好采用适当的异步方法(例如,迁移到 .NET Core 时)之前,它会很好地工作。AccessTokenProvider.AcquireAccessToken
如果基本控制器当前使用以下命令调用其 API,则最后一个选项也是可能的: 您可以使用委托处理程序来自动检索/刷新访问令牌。这实现起来有点复杂,但一旦到位,效果很好。如果基本控制器未用于调用 API,则此选项不可行。HttpClient
HttpClient
评论
下一个:异步方法无法返回布尔值
评论