我正在将当前项目迁移到核心,在我当前的项目中,我有许多来自Create
类的同步方法调用,如FindById
,AddToRole
,{{1}}等。但是,尽管在网上进行了彻底的搜索,我仍然无法在核心中找到相同的内容。
核心2.0中是否已弃用?如果没有,命名空间是什么以及如何包含它?
答案 0 :(得分:1)
据我所知,他们走了。然而,他们的存在甚至在此之前都是可疑的。所有扩展都只是“同步”运行异步版本,这基本上意味着他们分离了一个阻止异步调用的任务,直到它完成。虽然这在技术上满足了“同步”方法,但实际上对于Web应用程序来说真的很糟糕,因为你牺牲了池中的线程来同步完成工作。
在ASP.NET MVC中,它是一个必要的邪恶,因为有许多方面不支持异步:子操作,动作过滤器等。但是,在Core中,一切都是异步的,事情发生在Web应用程序空间应该是异步的。因此,没有充分的理由使用同步方法,这可能就是它们不再存在的原因。
如果您仍然需要将async方法作为sync运行,出于某种原因,您可以自行阻止它们:
var user = UserManager.FindByIdAsync(id).GetAwaiter().GetResult();
但是,请注意,由于上下文的转移,在某些情况下会出现僵局。避免这种情况的两种方法是:
使用ConfigureAwait(false)
var user = UserManager.FindByIdAsync(id).ConfigureAwait(false).GetAwaiter().GetResult();
但是,您不能在动作方法中使用ConfigureAwait(false)
,因为必须维护上下文才能完成响应。但是,您可以在action方法调用的方法中使用它:
private ApplicationUser GetUser(string id)
{
return UserManager.FindByIdAsync(id).ConfigureAwait(false).GetAwaiter().GetResult();
}
...
var user = GetUser(id);
在另一个帖子中运行
Task.Run(() => {
var user = UserManager.FindByIdAsync(id).GetAwaiter().GetResult();
// code here that needs `user`
});
正如您所看到的,使用此方法,您发送的工作必须是自包含的,因此在大多数情况下它可能不太合适。此外,这对于Web应用程序来说非常糟糕。
长而短,没有一种像同步一样运行异步的好方法,你应该尽可能地避免它。异步应该一直是异步的。这确实是MVC中的一个问题,但现在它不是Core。