简体   繁体   English

为什么此WCF服务一次只能为一个请求服务?

[英]Why can this WCF service serve only one request at a time?

I have seen several similar questions, but I couldn't solve this problem based on their answers. 我看过几个类似的问题,但根据他们的答案,我无法解决这个问题。

I have the following WCF service for communicating between to apps running on the same server, note that ConcurrencyMode is set to Multiple : 我有以下WCF服务用于在同一服务器上运行的应用程序之间进行通信,请注意ConcurrencyMode设置为Multiple

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple)]
internal class MyService : ServiceBase, IMyService
{
    ...
}

We have a WPF app in which we create the service instance the following way: 我们有一个WPF应用程序,我们通过以下方式创建服务实例:

var serv = new MyService();

var servHost = new ServiceHost(serv, new Uri("..."));

servHost.AddServiceEndpoint(typeof(IMyService), ServiceBase.DefaultInterProcessBinding, string.Empty);

servHost.Open();

Where ServiceBase.DefaultInterProcessBinding is the following: ServiceBase.DefaultInterProcessBinding的位置如下:

public static readonly Binding DefaultInterProcessBinding = new NetNamedPipeBinding()
{
    CloseTimeout = TimeSpan.FromHours(1),
    OpenTimeout = TimeSpan.FromHours(1),
    ReceiveTimeout = TimeSpan.MaxValue,
    SendTimeout = TimeSpan.FromHours(1),
    HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,
    MaxBufferSize = 1073741824,
    MaxBufferPoolSize = 524288,
    MaxReceivedMessageSize = 1073741824,
    TransferMode = TransferMode.Buffered,
    ReaderQuotas = new XmlDictionaryReaderQuotas()
    {
            MaxDepth = 32,
            MaxStringContentLength = 8192,
            MaxArrayLength = 16384,
            MaxBytesPerRead = 4096,
            MaxNameTableCharCount = 16384
    }
};

When we send multiple requests in parallel to this service, for some reason it only processes one single request at a time. 当我们并行向此服务发送多个请求时,由于某种原因,它一次只处理一个请求。 (It is easy to test deterministically, because we have rather long running requests, so it can be seen very clearly that we call 3 requests in parallel at the client side, and on the server side they are getting processed sequentially one at a time.) (确定性很容易测试,因为我们有相当长的运行请求,因此可以非常清楚地看到我们在客户端并行调用3个请求,而在服务器端,它们一次一个地顺序处理。 )

What can be the reason for this? 这可能是什么原因? What other config parameters should I check? 我应该检查哪些其他配置参数?

(UPDATE: the code I am calling the service from the client is similar to this: (更新:我从客户端调用服务的代码与此类似:

Task.Factory.StartNew(() =>
    {
        serviceClient.Foo();
    });
Task.Factory.StartNew(() =>
    {
        serviceClient.Bar();
    });
Task.Factory.StartNew(() =>
    {
        serviceClient.Baz();
    });

By debugging I can see, that all three requests are called immediately, but they are processed one at a time on the server.) 通过调试,我可以看到,所有三个请求都被立即调用,但它们在服务器上一次处理一个。)

UPDATE 2: The problem is probably not on the server, but on the client. 更新2:问题可能不是在服务器上,而是在客户端上。 If I create a new client object for the calls, then they get processed in parallel properly. 如果我为调用创建一个新的客户端对象,那么它们将被正确并行处理。 I create the client the following way: 我通过以下方式创建客户端:

var factory = new ChannelFactory<IMyService>(ServiceBase.DefaultInterProcessBinding, new EndpointAddress("..."));

serviceClient = factory.CreateChannel();

Should I configure something else on the factory or the channel? 我应该在工厂或渠道配置其他东西吗?

I figured out the problem wasn't on the server, but rather on the client side. 我发现问题不是在服务器上,而是在客户端。

It seems that if you create a channel with a ChannelFactory , you have to explicitly call Open() on it. 看来如果你用ChannelFactory创建一个频道,你必须在它上面显式调用Open() Otherwise the framework is going to call EnsureOpened() every time you call a request, and EnsureOpened() will block until the previous request is completed, so effectively only one request will be sent at a time. 否则,每次调用请求时框架都会调用EnsureOpened() ,并且EnsureOpened()将阻塞,直到上一个请求完成,因此实际上一次只发送一个请求。
(Details here: http://blogs.msdn.com/b/wenlong/archive/2007/10/26/best-practice-always-open-wcf-client-proxy-explicitly-when-it-is-shared.aspx ) (详情请见http://blogs.msdn.com/b/wenlong/archive/2007/10/26/best-practice-always-open-wcf-client-proxy-explicitly-when-it-is-shared。 aspx

So changing this code 所以改变这段代码

var factory = new ChannelFactory<IMyService>(ServiceBase.DefaultInterProcessBinding, new EndpointAddress("..."));

serviceClient = factory.CreateChannel();

to this: 对此:

var factory = new ChannelFactory<IMyService>(ServiceBase.DefaultInterProcessBinding, new EndpointAddress("..."));

serviceClient = factory.CreateChannel();
((IClientChannel)serviceClient).Open();

solved the problem, now the requests are sent properly in parallel. 解决了问题,现在请求是并行发送的。

(By the way I needed quite a lot of googling to find this solution, it's strange to me why this issue isn't advertised more strongly on MSDN.) (顺便说一句,我需要相当多的谷歌搜索来找到这个解决方案,我很奇怪为什么这个问题在MSDN上没有更强烈的广告宣传。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM