C#WCF客户端需要很长时间才能处于打开状态(DuplexClientBase<;T>;.Open())

本文关键字:lt DuplexClientBase Open gt 状态 于打开 客户端 长时间 C#WCF | 更新日期: 2023-09-27 18:00:43

我在WCF客户端上遇到了一个小问题。首先,请允许我向您解释并提供详细信息。

我目前正在开发一个系统,我正在考虑将主应用程序分开,因为我将其设计为使用dll进行更新。所以我找到了MEF,并开始阅读很多关于它的内容。但MEF有问题,它锁定了文件,无法写入。然后我找到了影子副本。因此,现在我将客户端放置在主应用程序的另一个AppDomain中。我读到通过NETRemoting可以实现跨域通信,所以我进行了研究并使用WCF进行了研究。

主应用程序是主机,它在新域中加载程序集并启动客户端。由于客户端是一个DLL,因此没有用于加载绑定、端点的AppConfig文件。我已经创建了一个类来帮助我,所以配置是通过程序添加的。

终于成功了!

但有一点我觉得不太好。在客户端,当执行DuplexClientBase.Open()指令时,需要20秒才能打开。我认为这是不好的,因为当我把客户端移到EXE(记住是一个DLL,配置是通过程序添加的)时,它不会花那么多时间。

也许配置中有问题,但我找不到。所以这里是souce代码文件。首先,当客户端位于控制台应用程序中时,这是App.config文件:

<configuration>
<system.serviceModel>
    <bindings>
        <netTcpBinding>
            <binding name="TcpBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
                receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
                transferMode="Buffered" transactionProtocol="OleTransactions"
                hostNameComparisonMode="StrongWildcard" listenBacklog="10"
                maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
                maxReceivedMessageSize="65536">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <reliableSession ordered="true" inactivityTimeout="00:10:00"
                    enabled="false" />
                <security mode="Transport">
                    <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
                    <message clientCredentialType="Windows" />
                </security>
            </binding>
        </netTcpBinding>
        <wsDualHttpBinding>
            <binding name="HttpBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
                receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
                transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <reliableSession ordered="true" inactivityTimeout="00:10:00" />
                <security mode="Message">
                    <message clientCredentialType="Windows" negotiateServiceCredential="true"
                        algorithmSuite="Default" />
                </security>
            </binding>
        </wsDualHttpBinding>
    </bindings>
    <client>
        <endpoint address="net.tcp://localhost:8080/ProtoServicio/EPServicioTcp"
            binding="netTcpBinding" bindingConfiguration="TcpBinding"
            contract="TestServicio.IServicio" name="TcpBinding">
            <identity>
                <userPrincipalName value="OlinzerLaptopV'Olinzer" />
            </identity>
        </endpoint>
        <endpoint address="http://localhost:8081/ProtoServicio/EPServicioHttp"
            binding="wsDualHttpBinding" bindingConfiguration="HttpBinding"
            contract="TestServicio.IServicio" name="HttpBinding">
            <identity>
                <userPrincipalName value="OlinzerLaptopV'Olinzer" />
            </identity>
        </endpoint>
    </client>
</system.serviceModel>

现在,这是创建绑定和端点的代码:

        internal static Binding GetBinding()
    {
        WSDualHttpBinding binding = new WSDualHttpBinding();
        TimeSpan span = new TimeSpan( 0, 1, 0 );
        binding.Name = "HttpBinding";
        binding.CloseTimeout = span;
        binding.OpenTimeout = span;
        binding.ReceiveTimeout = span;
        binding.SendTimeout = span;
        binding.BypassProxyOnLocal = false;
        binding.TransactionFlow = false;
        binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
        binding.MaxBufferPoolSize = 524288;
        binding.MaxReceivedMessageSize = 65536;
        binding.MessageEncoding = WSMessageEncoding.Text;
        binding.TextEncoding = Encoding.UTF8;
        binding.UseDefaultWebProxy = true;
        binding.ReaderQuotas = new XmlDictionaryReaderQuotas();
        binding.ReaderQuotas.MaxDepth = 32;
        binding.ReaderQuotas.MaxStringContentLength = 8192;
        binding.ReaderQuotas.MaxArrayLength = 16384;
        binding.ReaderQuotas.MaxBytesPerRead = 4096;
        binding.ReaderQuotas.MaxNameTableCharCount = 16384;
        binding.ReliableSession = new ReliableSession();
        binding.ReliableSession.Ordered = true;
        binding.ReliableSession.InactivityTimeout = span;
        binding.Security.Mode = WSDualHttpSecurityMode.Message;
        binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
        binding.Security.Message.NegotiateServiceCredential = true;
        binding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;
        return binding;
    }

代码创建的文件只包含Http端点。也许添加tcp端点会造成差异,但我不知道如何实现。上面的函数是由ClientClientBase类的构造函数调用的。

ServiceModel.DuplexClientBase<Servicio> MyClient = new ...<Servicio>(new InstanceContext(this), GetBinding(), GetEndpoint());

如果你还需要什么,随时通知我。

C#WCF客户端需要很长时间才能处于打开状态(DuplexClientBase<;T>;.Open())

您在单个进程内进行跨AppDomain通信,而您使用的是WsHttpBinding?你知道这有多大的开销吗?它还大大增加了应用程序部署的复杂性。这可能不是你主要问题的来源,但我会从开始

  • NetNamedPipeBinding代替WsDualHttpBinding

若要诊断您的问题,请从WCF跟踪开始,并检查客户端和服务器上的哪个操作需要很长时间——由于您的设置使用了消息安全性,某些安全性解决可能会出现问题。