2

我只是在整理我的一些 WCF(自托管)代码,并意识到我的 ServiceHost 对象在最初设置后超出了范围,但我仍然可以连接到它。

public void StartMyService()
{
    var host = new ServiceHost(typeof(MyService), new Uri("http://localhost:8000/MyService"));
    host.Open();
}

如果我再次调用它并重新实例化它并尝试再次打开它,我会收到一条错误消息,指出已经有一些东西连接到端点。它仅在应用程序关闭时才被释放。

我只能假设对 Open() 的调用在较低级别上做了一些事情,以使其以现在不受管理的方式保持打开状态。但是,除非我在这里完全误解了事情,否则我找不到任何有关此的信息。

考虑一下,连接现在仍然打开,但我无法在不杀死应用程序的情况下恢复它(关闭等),这似乎并不正确。或者也许这甚至无关紧要,如果它不伤害任何东西,我可以一直让它打开?

更新:所以我接受了 Eiver 的回答,因为它解释了我最初的问题,即为什么即使在超出范围后它仍然保持打开状态。但是,我现在想知道一些关于此的事情(或者我可能对线程缺乏经验)。首先,只要它是开放的,我是否会为此烦恼,这一切都是正确的。如果有某种方法可以通过将线程保持在范围内来访问线程,它甚至会有所帮助。也许,像这样设置它(并且从不调用 close)使调用代码变得简单(即不必保留引用),我什至可以将它包装在一个静态方法中以进行更简单的调用。听起来有点躲闪……嗯!

更新2:所以,我知道这样做不好,因为这意味着我不再控制主机和启动它的线程。所以我把它全部包装成一个单例,让我能够在任何时候访问主机(对于错误、事件、在同一端点上关闭/重新打开等)并使调用非常简单(就像一个简单的静态方法称呼)。

4

3 回答 3

1

My guess is the Class with the method StartMyService() is still alive. If you code it like this it does what (I think) it is supposed to do. Left the commented out code as I think that is a cleaner way of starting a service and letting it go out of scope.

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("**** Console Based WCF Host *****");

            //using (ServiceHost serviceHost = new ServiceHost(typeof(MagicEightBallService)))
            //{
            //    serviceHost.Open();
            //    Console.WriteLine("The service is running");
            //    Console.ReadLine();
            //}
            using (MySvc ms = new MySvc())
            {
                ms.StartMyService();
            }
            Console.ReadLine();
        }

        public class MySvc: IDisposable
        {
            ServiceHost serviceHost;
            public void StartMyService()
            {
                serviceHost = new ServiceHost(typeof(MagicEightBallService));
                serviceHost.Open();
            }
            public void Dispose() 
            {
                // the class needs to clean up after itself
                serviceHost.Close();
            }
            public MySvc() { }
        }
    }
于 2012-07-13T19:00:03.610 回答
1

并非所有超出范围的内容都会被终止。如果一个类产生另一个线程(我确信 WCF 会这样做),即使对创建它的类的引用被垃圾回收,该线程也可能存在。

您可能需要调用 host.Close()

于 2012-07-13T17:49:11.880 回答
0

在您尝试访问它之前,它可能没有被收集。

于 2012-07-13T16:34:50.637 回答