簡體   English   中英

在 WCF 自托管中第一次失敗時,ServiceHost 無法使用新的 ServiceHost 實例再次打開()

[英]ServiceHost fail to Open() again with new ServiceHost instance when it failed for the first time in WCF self-host

我的症狀與這篇文章描述的完全一樣http://social.msdn.microsoft.com/Forums/vstudio/en-US/302ca96e-a810-4958-9905-90ba1175765d/servicehost-does-not-detech-endpoints-cant-從故障狀態恢復

我想知道這是否是一個已知的錯誤。

我的代碼與 Dave 的代碼略有不同,而他的 ServiceHost 實例(名為 WebService)在 Start() 方法之外。 我的 ServiceHost 實例(命名主機)在里面聲明。 在調試的時候,我在 Host Description 中檢查端點的地址已更改為正確的 IP。 但是,Open() 仍然會使用舊的錯誤 IP 地址引發異常。

    private bool InitHost(PtiType type, string serverIp, int portNumber)
    {
        if (!HostDictionary.ContainsKey(type))
        {
            Uri addressBase = new Uri(String.Format("net.tcp://{0}:{1}/CommunicationService/{2}", serverIp, portNumber.ToString(), type.ToString()));
            var service = new PtiCommunicationService(type);

            service.ClientConnected += service_ClientConnected;
            service.ClientBroadcasted += service_ClientBroadcasted;
            service.ClientSentTo += service_ClientSentTo;
            service.ClientDisconnected += service_ClientDisconnected;

            var host = new ServiceHost(service, addressBase);

            //For publishing metadata only
            //Define Metadata endPoint, So we can publish information about the service
            ServiceMetadataBehavior mBehave = new ServiceMetadataBehavior();
            host.Description.Behaviors.Add(mBehave);

            //Enable debug info in fault
            ((ServiceDebugBehavior)host.Description.Behaviors[typeof(ServiceDebugBehavior)]).IncludeExceptionDetailInFaults=true;

            host.AddServiceEndpoint(typeof(IPtiCommunication), new NetTcpBinding(SecurityMode.None), "");
            host.AddServiceEndpoint(typeof(IMetadataExchange),
                MetadataExchangeBindings.CreateMexTcpBinding(),
                "mex");

            try
            {
                host.Open();

                //Add host to dictionary to keep track
                HostDictionary.Add(type, host);

                LogList.Add(String.Format("{0}\tThe service {1} at {2} is ready", DateTime.Now.ToLongTimeString(), service.ServiceType.ToString(), serverIp));

                string hostInfo = String.Format("{0}\tHost information:\n", DateTime.Now.ToLongTimeString());

                hostInfo += "Enpoints details:\n";
                foreach (var endpt in host.Description.Endpoints)
                {
                    hostInfo += String.Format("\t Name:\t\t{0}\n", endpt.Name);
                    hostInfo += String.Format("\t Logical address:\t{0}\n", endpt.Address);
                    hostInfo += String.Format("\t Physical address:\t{0}\n", endpt.ListenUri);
                    hostInfo += String.Format("\t Binding:\t\t{0}\n", endpt.Binding);
                    hostInfo += String.Format("\t Contract:\t{0}\n\n", endpt.Contract.ContractType.Name);
                }
                LogList.Add(hostInfo);
            }
            catch (Exception e)
            {
                host.Abort();
                host = null;
                LogList.Add(String.Format("{0}\t{1}", DateTime.Now.ToLongTimeString(), e.Message));
            }
            return true;
        }
        return false;
    }

這是我的 PtiCommunicationService ServiceBehavior

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
 ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]

和接口的 ServiceContract

[ServiceContract(CallbackContract = typeof(IPtiCommunicationCallback), SessionMode = SessionMode.Required)]

app.config 中沒有其他配置。 都在代碼中。

謝謝

更新:

我發現我們兩個都對 ServiceHost Constructor (Object, Uri[]) 使用了相同的重載,它們構成了 Web 服務的單例。

當我們使用相同的單例創建新的服務主機時,以某種方式更改端點地址不會產生影響,因為即使主機已中止,服務實例仍然存在。

當我們創建新主機時,是否有任何解決方案來清理該單例?

以上是我的疑惑,如有不對請指正。

顯然 WCF 緩存了一些套接字信息。 我發現的最佳解決方法是由 Ivan 在此處提供的https://stackoverflow.com/a/6839265/955400 在嘗試調用 host.Open() 之前,您檢查是否可以打開連接。

暫無
暫無

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

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