c# - 为什么此 WCF 服务一次只能处理一个请求?

标签 c# .net wcf concurrency

我看过几个类似的问题,但是根据他们的回答我无法解决这个问题。

我有以下 WCF 服务用于在同一服务器上运行的应用程序之间进行通信,请注意 ConcurrencyMode 设置为 Multiple:

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

我们有一个 WPF 应用程序,我们在其中按以下方式创建服务实例:

var serv = new MyService();

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

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

servHost.Open();

其中 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
    }
};

当我们向该服务并行发送多个请求时,出于某种原因它一次只处理一个请求。 (确定性测试很容易,因为我们有相当长的运行请求,所以可以非常清楚地看到我们在客户端并行调用 3 个请求,而在服务器端,它们一次一个地顺序处理。 )

这可能是什么原因?我应该检查哪些其他配置参数?

(更新:我从客户端调用服务的代码与此类似:

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

通过调试我可以看到,所有三个请求都被立即调用,但它们在服务器上一次处理一个。)

更新 2:问题可能不在服务器上,而是在客户端上。如果我为调用创建一个新的客户端对象,它们就会得到正确的并行处理。我通过以下方式创建客户端:

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

serviceClient = factory.CreateChannel();

我应该在工厂或 channel 上配置其他东西吗?

最佳答案

我发现问题不在服务器上,而是在客户端。

似乎如果您使用ChannelFactory 创建一个 channel ,您必须显式调用Open()。否则,每次调用请求时,框架都会调用 EnsureOpened(),而 EnsureOpened() 将阻塞,直到上一个请求完成,因此实际上只有一个请求会一次发送。
(详情在这里:http://blogs.msdn.com/b/wenlong/archive/2007/10/26/best-practice-always-open-wcf-client-proxy-explicitly-when-it-is-shared.aspx)

所以改变这段代码

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

serviceClient = factory.CreateChannel();

为此:

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

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

问题已解决,现在请求已正确并行发送。

(顺便说一句,我需要大量谷歌搜索才能找到这个解决方案,我很奇怪为什么这个问题没有在 MSDN 上更强烈地宣传。)

关于c# - 为什么此 WCF 服务一次只能处理一个请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25760046/

相关文章:

c# - 在 iOS 上为 .NET Maui 应用程序创建安装程序 - Visual Studio

c# - 如何在 AboutBox 的描述字段内显示超链接

c# - 为什么 GetEntryAssembly 返回 null?

wcf - C# 4.0 WCF REST JSON - HTTP GET 代码 400 错误请求

c# - 使用 WCF 访问 SQL Server : Timeout

c# - 从 property 属性获取数据

c# - 如何在执行功能期间制作应用程序加载屏幕

c# - 为什么 Visual Studio 要求强命名程序集?

c# - 有没有办法避免方法重复调用?

asp.net - 在 IIS 中使用 SSL 安全访问 WCF 时出现证书不受信任错误