我有一个WPF应用程序,它做的非常简单。我只是将4
个请求发送给基本的WCF Service
。
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"/>
中添加了web.config
int,但没有任何区别。因此,然后我阅读了我的代理可能达到的连接限制,因此我在WPF应用程序中添加了ServicePointManager.DefaultConnectionLimit=10;
。
线程饥饿
然后,我一直遇到线程饥饿的情况。因此,作为一个测试,我试图将最小线程数设置为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个请求在3秒后被记录了。 / p>
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);
}
}
答案 0 :(得分:1)
经过大量研究,this是我发现的唯一可以解释这种现象的东西。我在IIS 8
上运行Windows 10
。尽管我找不到确切版本组合的限制,但我认为这可能是个问题。
Microsoft似乎会限制同时请求的数量。对于某些基本版本,限制为3。我似乎无法在任何地方更改这些设置,因此,如果您知道怎么做,请为遇到此问题的其他人发布另一个答案。