C# 在getter内调用异步方法会引发异常
我已经构建了一个API端点来从中获取可用的语言。在我的C# 在getter内调用异步方法会引发异常,c#,asynchronous,task-parallel-library,C#,Asynchronous,Task Parallel Library,我已经构建了一个API端点来从中获取可用的语言。在我的MVC应用程序中,我有一个助手来异步获取语言。该方法的定义如下: public static async Task<Languages> GetLanguagesAsync() { var apiResponse = await APIHelper.GetContentGetAsync("Languages").ConfigureAwait(false); return apiResponse.LanguagesD
MVC
应用程序中,我有一个助手来异步获取语言。该方法的定义如下:
public static async Task<Languages> GetLanguagesAsync()
{
var apiResponse = await APIHelper.GetContentGetAsync("Languages").ConfigureAwait(false);
return apiResponse.LanguagesDataModel;
}
然而,我总是在第var result=GetLanguagesAsync()行得到一个错误
哪一个答案的得票率最高
引发的异常是
此时无法启动异步操作。异步操作只能在异步处理程序或模块内启动,或在页面生命周期中的某些事件期间启动。如果在执行页面时发生此异常,请确保已标记该页面。此异常还可能表示有人试图调用“async void”方法,这在ASP.NET请求处理中通常不受支持。相反,异步方法应该返回一个任务,调用方应该等待它
如前所述,被调用的操作被标记为
async
Razor代码现在无法处理异步调用,即使您使用同步阻塞(这会导致)包装这些调用。操作是async
这一事实无关紧要,因为这是在操作完成后的视图处理期间
异步视图已添加到ASP.NET核心;然而,它仍然应该是一个不常见的用例
一般来说,您的选择是:
- 使助手“一路”同步;i、 例如,使用同步API调用,而不是异步调用,并摆脱异步代码上的同步
- 将数据添加到视图模型中(可能作为公共VM库的一部分)
在这种情况下,我同意Panagiotis的评论,即这种不变的信息应该只在每个应用程序中加载一次,而不是每次调用中加载一次。将同步实现封装在一个
惰性的中将是最简单的解决方案。消息还不够清楚吗?您必须在页面中使用
指令。我怀疑您使用的是旧的ASP.NET MVC版本,因为最新版本不需要它。这与async/await
关键字无关。请不要使用.Result
,而是使用await-GetLanguagesAsync()
@Mafli没有异步属性在任何情况下,尝试在ViewModel属性中执行操作意味着存在严重的设计问题。控制器应向视图发送完整的ViewModel。应该不需要从VM内部执行方法。因此,编写异步控制器要容易得多。您不必在每次调用时异步加载该值,这更糟糕。更好的选择是加载查找数据一次,例如当应用程序启动并缓存它时。您可以为此使用静态属性、缓存、注入列表等。您甚至可以使用Lazy
在首次使用时加载和缓存数据,感谢您的澄清。如前所述,我已经更改了代码,以便在需要时同步获取数据一次,并将结果存储在一个Lazy
文件中。
public static IEnumerable<SelectListItem<string>> AvailableLanguages
{
get
{
var result = GetLanguagesAsync().Result;
return new List<SelectListItem<string>>(result.Languages.Select(l => new SelectListItem<string> {Value = l.Key, Text = l.Value}));
}
}