为啥我的 WCF 服务一次只处理 3 个并行请求?
Posted
技术标签:
【中文标题】为啥我的 WCF 服务一次只处理 3 个并行请求?【英文标题】:Why is my WCF service only processing 3 parallel requests at a time?为什么我的 WCF 服务一次只处理 3 个并行请求? 【发布时间】:2019-01-18 16:17:51 【问题描述】:我有一个 WPF 应用程序做一些非常简单的事情。我只是让它触发4
对基本@987654323@ 的请求。
private async Task MultipleWcfCalls()
ServiceReference.Service1Client _proxy = new ServiceReference.Service1Client();
_proxy.Open();
var t1 = _proxy.GetDataAsync(0);
var t2 = _proxy.GetDataAsync(0);
var t3 = _proxy.GetDataAsync(0);
var t4 = _proxy.GetDataAsync(0);
await Task.WhenAll(t1, t2, t3, t4);
我的服务是做经典的Task.Delay(3000)
。
public async Task<string> GetDataAsync(int value)
int other = 0;
int workerThreadsAvail = 0;
ThreadPool.GetMinThreads(out workerThreadsAvail, out other);
await Task.Delay(3000);
return workerThreadsAvail.ToString();
我希望4
请求被触发,而3
秒后,我希望所有四个请求都返回。嗯,实际发生的情况是所有四个请求都通过网络发送,前三个请求将返回,然后最后一个请求将在之后返回 3
。
节流
起初我以为这是我的问题。好吧,我添加了<serviceThrottling maxConcurrentCalls="10"/>
int 我的web.config
并没有任何区别。所以,然后我读到它可能是我使用代理达到的连接限制,所以我将ServicePointManager.DefaultConnectionLimit=10;
添加到我的 WPF 应用程序中。
线程饥饿
然后,我不断遇到线程饥饿。因此,作为一个测试,我尝试将最小线程数设置为20
,以确保我有足够的速度来处理4
请求。我将此添加到我的 WPF 应用程序ThreadPool.SetMinThreads(20, 20);
。因此,为了确认有大量工作线程可用于处理请求,我决定让我的服务调用在进程开始时返回可用线程的数量。每个请求都返回19
或20
。
使用 Fiddler,我可以确认所有 4
请求都已从 WPF(客户端)应用程序通过网络发送。现在,我的 Wcf 正在使用 basicHttpBinding
,所以它在 Per Call
实例模式下运行,所以并发模式应该无关紧要,但为了安全起见,我添加了 [ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple)]
。
我已经使用System.Diagnostics.XmlWriterTraceListener
进行了一些堆栈跟踪,我可以确认我收到了3
请求同时记录(几乎),然后第四个请求在 3 秒后被记录。
Wcf 托管在IIS
。如果需要更多信息,请告诉我,我会尽快添加。
根据要求,这是我的 WCF 界面。
namespace SampleWCF
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IService1
[OperationContract]
System.Threading.Tasks.Task<string> GetData(int value);
【问题讨论】:
这是否与处理器中的核心有关,quad = 4, 4-1 = 3 thread。 @AnirudhaGupta 我不太了解这些东西,但我相信我在六核处理器上运行。 如果在 WCF 代码中执行await Task.Delay(3000).ConfigureAwait(false)
是否相同?你能检查一下那里是否有任何同步上下文(SynchronizationContext.Current?.GetType()?.Name
)吗?
另外请注意,WCF 和 WPF 中的异步是完全独立的——您可以调用同步的异步方法,反之亦然。所以忽略 WPF 部分,这都是关于 WCF 的。
@James,从您对 cmets 的回答来看,很明显这是特定于您的 IIS 配置的。很难在无法复制的情况下进一步发展。我建议您尝试WorkerThreadPoolBehavior
并确保服务在其自己的 IIS 应用程序池中运行。这是另一篇有用的 MSKB 文章,用于进一步排除故障:Contention, poor performance, and deadlocks when you make calls to Web services from an ASP.NET application。如果您找到它,请发布您自己的答案。
【参考方案1】:
经过大量研究,this 是我发现的唯一可以解释这种行为的东西。我在Windows 10
上运行IIS 8
。虽然我找不到我的确切版本组合的限制,但我认为这可能是问题所在。
微软似乎会限制同时请求的数量。对于某些基本版本,3 将是限制。我似乎无法在任何地方更改这些设置,所以如果您知道如何,请为遇到此问题的其他人发布另一个答案。
【讨论】:
确实很有趣,而且它在没有适当的解决方法之前就已经浮出水面(除了一些建议使用 IIS Express):***.com/q/33024015/1768303以上是关于为啥我的 WCF 服务一次只处理 3 个并行请求?的主要内容,如果未能解决你的问题,请参考以下文章
如何实现一次只为 1 个客户端提供服务的 WebSocket 服务器