簡體   English   中英

C# WCF 客戶端打開時間過長 state (DuplexClientBase<t> 。打開())</t>

[英]C# WCF Client takes too long to opened state (DuplexClientBase<T>.Open())

我在使用 WCF 客戶端時遇到了一點問題。 首先,請允許我向您解釋並提供詳細信息。

我目前正在開發一個系統,我正在考慮單獨的主應用程序,因為我將它設計為使用 dll 進行更新。 所以我找到了 MEF,並開始大量閱讀它。 但是MEF有問題,它鎖定了文件,沒有寫入。 然后我找到了影子副本。 所以現在我將客戶端放在主應用程序的另一個 AppDomain 中。 我已經讀過可以通過 NET Remoting 進行跨域通信,因此我進行了研究並使用 WCF 完成了它。

主應用程序是主機,它將程序集加載到新域中並啟動客戶端。 由於客戶端是 DLL,因此沒有 AppConfig 文件來加載綁定、端點。 我創建了一個 class 來幫助我,所以配置是以編程方式添加的。

最后,它起作用了!

但是有一點我覺得不太好。 在客戶端,當指令 DuplexClientBase.Open() 被執行時,需要 20 秒才能打開。 我認為這不好,因為當我將客戶端移動到 EXE 時(記住是 DLL 並且配置是通過編程方式添加的)它並不需要所有時間。

也許是配置中有問題,但我找不到。 所以這里是源代碼文件。 首先,這是 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 Endpoint。 也許添加 tcp 端點可能會有所不同,但是,我不知道如何做到這一點。 上面的function是由ClientClientBase class的構造函數調用的。

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

如果您需要其他任何東西,請隨時通知我。

您正在單個進程中進行跨 AppDomain 通信並且正在使用WsHttpBinding 你知道這有多大的開銷嗎? 它還極大地增加了應用程序部署的復雜性。 它可能不是您的主要問題的根源,但我將從:

  • NetNamedPipeBinding替換WsDualHttpBinding

要診斷您的問題,請從WCF 跟蹤開始,並檢查客戶端和服務器上的哪些操作需要很長時間 - 由於您的設置使用消息安全性,因此某些安全性解決可能會出現問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM