Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SNIReadSyncOverAsync和WaitForSingleObject阻止EF性能?_C#_.net_Wcf_Entity Framework 4 - Fatal编程技术网

C# SNIReadSyncOverAsync和WaitForSingleObject阻止EF性能?

C# SNIReadSyncOverAsync和WaitForSingleObject阻止EF性能?,c#,.net,wcf,entity-framework-4,C#,.net,Wcf,Entity Framework 4,我正在对一个WCF服务进行一些评测,该服务使用EF(System.Data.Entities)从SQL数据库中读取数据。当我启动多个运行该服务的并行客户机时,CPU都会达到100%,性能通常会下降,一切都会陷入困境 在使用并发分析器对此进行分析时,我发现85%的时间用于同步,只有大约4%的时间用于实际代码执行。深入查看堆栈跟踪,大多数同步似乎来自对System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync中的WaitForSin

我正在对一个WCF服务进行一些评测,该服务使用EF
(System.Data.Entities)
从SQL数据库中读取数据。当我启动多个运行该服务的并行客户机时,CPU都会达到100%,性能通常会下降,一切都会陷入困境

在使用并发分析器对此进行分析时,我发现85%的时间用于同步,只有大约4%的时间用于实际代码执行。深入查看堆栈跟踪,大多数同步似乎来自对
System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync
中的
WaitForSingleObject
的调用。堆栈显示调用转到本机方法包装器,然后在
kernel32.dll结束_WaitForSingleObject

以前有人经历过吗?有什么办法可以解决这个问题吗?我并不是真的在这里抛出荒谬的负载,只有大约20个并行客户端,而且都是只读的,所以我很惊讶线程甚至会费心同步


我已经为此奋斗了一个星期,我就是解释不了。任何帮助都将不胜感激

您是否能够将其提取为再现问题的小代码示例?您使用的是什么版本的EF

以下是根据您目前提供的信息得出的一些观察结果

EF异步 任何小于EF 6的都是同步的。使用EF 6,您可以选择使用。但是,除非您的WCF服务也使用异步模式,否则不要这样做

异步的 您可以编写实现为异步的WCF服务。有关更多信息,请参阅

如果使用上述方法之一,但不能同时使用这两种方法,则代码将不是异步的,但会产生不必要的同步开销。尤其要避免使用
Task.Run()
或类似的工具,因为它们只会将工作转移到另一个线程,而不会实际提高吞吐量

初始化
最后,另一个无关的想法。您的问题是否与EF初始化有关?当EF为模型构建元数据时,它会对每个连接字符串执行一次。如果多个线程尝试使用同一模型,但该模型尚未初始化,则所有线程都将阻塞,直到初始化完成。若要查看这是否是您的问题,请致电该服务并让其完成。然后提交20个并行请求。他们是否仍在最大限度地使用CPU?

客户端是否正在等待服务器的响应?客户端肯定在等待,但它正在另一台机器上运行。。此分析来自服务器,不应等待任何东西。SQL也被转移到另一台机器上,它几乎不需要注册cpu使用率(1%)和网络(这很奇怪,线程实际上似乎什么都没有做,它们都处于“同步”状态。我还运行了debugdiag,max CPU的前10个线程都显示了相同的情况:这显然是同步的。没有回调,也没有任务。所以它是同步的(这一点没有错)。您可以自由选择同步或异步,但必须保持一致。我建议您坚持同步。我怀疑
SNIReadAsyncOverAsync()
是由ADO.NET在繁忙循环中调用的,当SQL Server发送部分响应,然后花费非零的时间发送后续响应时。我认为,它获取行数据这一事实表明,应该同步读取更多行数据,以填充它拥有的一些缓冲区,即使SQL Server可能不为lon提供数据g时间。我自己也因为这个。也许它是忙着循环而不是为你阻塞