这是工作流程:
在映射操作很快的情况下,我很幸运。但是如果我添加Task.Delay(2000)
,那么我会得到有问题的异常。似乎ASP.NET没有“等待”我的异步lamba完成?
这是映射表达式的主体:
mapping.AfterMap(async (entity, model) => {
var child = await _childRepo.Get(entity.ChildId);
await Task.Delay(2000); // For testing, of course.
if (child != null)
{
// Fill in some properties on model
}
});
请注意,这是示例代码,我不打算在“真实生活”中进行映射期间进行额外的DB / repo调用。
答案 0 :(得分:2)
AfterMap
takes an Action
,这是synchronous delegate, not an asynchronous delegate(正如我在博客中解释的那样)。因此,它与@
lambdas无法正常工作。
在这种情况下(因为委托返回@using(Html.BeginForm("Index", "Manage", FormMethod.Post, new { @class = "form-inline", Id = "ManageEmployeeForm" }))
{
@Html.AntiForgeryToken();
@Html.HiddenFor(m => m.ActionForm.From);
@Html.HiddenFor(m => m.ActionForm.To);
<div class="form-group">
@Html.LabelFor(m => m.ActionForm.UserId, new { @class = "sr-only" });
@Html.DropDownListFor(x => x.ActionForm.UserId, Model.Users, new { @class = "form-control" });
@Html.ValidationMessageFor(m => m.ActionForm.UserId);
</div>
....
),编译器实际上将允许async
lambda;但是,它将编译为void
方法。 (编译器执行此操作以允许async
事件处理程序)。正如我在关于异步最佳实践的MSDN文章中所描述的那样,您应该avoid async void
。
避免async void
的一个原因是很难检测async
方法何时完成。事实上,(除了WebForm生命周期事件),ASP.NET甚至都不会尝试这样做。