Xer*_*ati 22 .net c# entity-framework entity-framework-4
我正在对使用EF(System.Data.Entities)从sql DB读取的WCF服务进行一些分析.当我启动多个并行服务器的客户端时,CPU都会达到100%,性能通常是坦克,一切都陷入困境.
在使用并发分析器进行分析时,我发现85%的时间花在同步上,只有大约4%是实际的代码执行.深入研究堆栈跟踪,大多数同步似乎来自System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync中对WaitForSingleObject的调用.堆栈显示调用转到本机方法包装器,然后在kernel32.dll!_WaitForSingleObject结束.
有谁之前经历过这个吗?对此有什么办法吗?我并没有真正抛出荒谬的负载,只有大约20个并行客户端,并且它都是只读的,所以我很惊讶线程甚至会费心去同步.
我已经和它斗争了一个星期了,我无法解释它.任何帮助,将不胜感激!
您能否将其提炼为重现问题的小代码示例?您使用的是哪个版本的 EF?
以下是根据您目前提供的信息得出的一些观察结果。
小于 EF 6 的任何内容始终是同步的。使用 EF 6,您可以选择使用异步方法。但是,除非您的 WCF 服务也使用异步模式,否则不要这样做。
您可以编写一个异步实现的 WCF 服务。请参阅此文档以获取更多信息。
如果您使用上述方法之一,而不是同时使用两者,您的代码将不是异步的,而是会产生不必要的同步开销。尤其要避免Task.Run()
或等效,因为它们只会将工作转移到另一个线程,而实际上不会提高吞吐量。
最后,另一个不相关的想法。您的问题可能与 EF 初始化有关吗?当 EF 为模型构建元数据时,它会对每个连接字符串执行一次此操作。如果多个线程尝试使用同一模型并且该模型尚未初始化,则所有线程将阻塞,直到初始化完成。要查看这是否是您的问题,请拨打该服务一次并允许其完成。然后提交 20 个并行请求。他们仍然会最大化 CPU 吗?