C# 实体框架6-强制异步查询,编译时阻止同步调用
随着迁移到EF6.1,我们的目标是使用专用性—异步/等待选项与数据集对话。在从以前的Linq2Sql进行移植时,有许多.ToList()、.FirstOrDefault()和.Count()。我知道我们可以搜索并修复所有这些函数,但如果我们能够在编译时阻止这些函数被允许进入构建,那就太好了。有没有人对如何做到这一点有创造性的想法?即使它们是可能抛出的编译器警告(例如使用过时属性)。您可以使用编写一个用于查找这些模式并提供警告/错误的C# 实体框架6-强制异步查询,编译时阻止同步调用,c#,.net,entity-framework,asynchronous,entity-framework-6,C#,.net,Entity Framework,Asynchronous,Entity Framework 6,随着迁移到EF6.1,我们的目标是使用专用性—异步/等待选项与数据集对话。在从以前的Linq2Sql进行移植时,有许多.ToList()、.FirstOrDefault()和.Count()。我知道我们可以搜索并修复所有这些函数,但如果我们能够在编译时阻止这些函数被允许进入构建,那就太好了。有没有人对如何做到这一点有创造性的想法?即使它们是可能抛出的编译器警告(例如使用过时属性)。您可以使用编写一个用于查找这些模式并提供警告/错误的 您甚至可以实现一个语法转换来自动更改这些结构,尽管这项工作可能
您甚至可以实现一个语法转换来自动更改这些结构,尽管这项工作可能比手工操作更昂贵。接下来。。。我从未找到一个解决方案可以在编译时检测到这一点,但我能够在DataContext的代码中做到这一点:
public EfMyCustomContext(string connctionString)
: base(string.Format(CONNECTION_STRING, connctionString))
{
#if DEBUG
this.Database.Log = LogDataBaseCall;
#endif
}
#if DEBUG
private void LogDataBaseCall(string s)
{
if (s.Contains("Executing "))
{
if (!s.Contains("asynchronously"))
{
// This code was not executed asynchronously
// Please look at the stack trace, and identify what needs
// to be loaded. Note, an entity.SomeOtherEntityOrCollection can be loaded
// with the eConnect API call entity.SomeOtherEntityOrCollectionLoadAsync() before using the
// object that is going to hit the sub object. This is the most common mistake
// and this breakpoint will help you identify all synchronous code.
// eConnect does not want any synchronous code in the code base.
System.Diagnostics.Debugger.Break();
}
}
}
#endif
希望这对其他人有所帮助,如果在编译过程中有一些选项,我仍然会很高兴。使用基于的分析器应该非常简单。我只是想让您知道,在99%的情况下,异步db调用是没有意义的,甚至对项目有害:在我们的环境中,我们的API位于IIS之下,其中线程池线程非常有价值。我们遇到过这样的情况(可伸缩性),即IIS由于传入的请求数量而缺少线程。大多数调用都在等待返回DB查询,或读取磁盘数据,从而导致IIS在等待释放线程时对请求进行排队。有人会说“只需添加更多线程”,但这不是我们想要采取的方法。转移到异步任务是我们决定要做的事情,到目前为止(时间会告诉我们),我们还没有遇到任何问题。也许你是对的,但也许正确的答案是将min threads设置为500,然后完成。如果您的队列超过了这个数量,那么无论您使用的是什么后端(db/磁盘),后端都无法处理它。但是从你的描述来看,使用AcYNC的边界是有意义的:)你是否考虑过最热门的查询异步和剩下的同步?似乎是一个更好的权衡。异步是对代码质量的毒药。关键是不要有500个线程,每个线程使用1兆内存,并在CPU上创建很多争用。这不是一个可伸缩的方法。通过一些异步和一些同步,您仍然会遇到相同的问题。通过实施异步模型(我最初的问题),您鼓励/强制您的开发人员使用最适合可伸缩性的模式,而不是易于开发的模式。即使是一个查询,其中人类的东西是“快的”(即100毫秒),一次阻塞该线程x 1000个用户,也意味着您将更快地耗尽您的线程池。顺便说一句,这不是毒药——它很优雅。是的,确实考虑过罗斯林,那是一个老学校的FXCOP,但要学的时间要长一点。如果我想要编译时警告或错误,这可能是唯一的赌注。