Click here to Skip to main content
15,893,487 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I'm trying some samples with wcf where i start the host and some clients. Inside the Service I log construction and destruction of the service objects.

I can see, whenever I connect a new client, a new Service-object is created. But whenever I close the client, the Service-object is NOT destructed.

Is there a way to dispose unused Service-instances ?

my Host:

C#
namespace wcf_Test.Host
{
	public class Params
	{
		public string conn="net.pipe://localhost/myPipe";
		public NetNamedPipeBinding binding=new NetNamedPipeBinding();
	}

	class Program
	{
		public static void Main(string[] args)
		{
			Params cPar=new Params();
 			using (var host = new ServiceHost(typeof (MyService), new Uri(cPar.conn)))
            {
           
           		host.AddServiceEndpoint(typeof (Itest), cPar.binding,"");
          		host.Open();
          		Console.WriteLine("Service running. Press ENTER to stop.");
                        Console.ReadLine();
                ((IDisposable)host).Dispose();
            }
 			 Console.ReadLine();
 			 Console.WriteLine("This is the end");
            }
		}
	}
}


here is my Service:

C#
namespace wcf_Test.Service
{
	[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
	public class MyService: Itest
	{
		public IMyCallback callback;
		public Timer timer;

		private int a=1;
		private static int sID=0;
		private int ID=0;

		
		
		public MyService()
		{
			ID=++sID;
			Console.WriteLine("Contructor ID=  {0}",ID);
			callback = OperationContext.Current.GetCallbackChannel<IMyCallback>();	
			
			timer = new Timer(1000);
            timer.Elapsed += OnTimerElapsed;
            timer.Enabled = true;
        }
		~MyService()
		{
			Console.WriteLine("Destructor ID= {0}",ID);	
		}
 
        void OnTimerElapsed(object sender, ElapsedEventArgs e)
        {
            callback.OnCallback();
        }
			
		
		public string getText()
		{		
			return string.Format("Hello from {0}, call number: {1}",ID, a++);
		}
		public void write (string text)
		{
			Console.WriteLine(text);
		}
		public void init()
		{}
	}
}


I tried to insert a screenshot but there's no option to do so, so here is the Output of the Host application after i added your code:

Service running. Press ENTER to stop.
Contructor ID= 1
Contructor ID= 2

//I started and closed two clients here...

This is the end
Destructor ID= 2
Destructor ID= 1


as you can see the instances of the service-object remain active till the application is closed. I closed both clients before pressing the key!
Posted
Updated 13-Apr-15 23:41pm
v3
Comments
Afzaal Ahmad Zeeshan 14-Apr-15 4:31am    
First of all, your connection is not closed; there is no host.Close() in your code. Secondly, you do not overload the destructors but you can somehow do add the logic to destruct the objects. But I do not find your question enough logical, please see Solution 1 for more.
Florian Braun 14-Apr-15 4:54am    
Well I want to keep the host running for other clients. So I guess a call of host.close would close every connection to still running clients.

The question is:
* each clients gets a new instance of the service-object. The constructor runs everytime i open a connection. (reading this article: http://www.codeproject.com/Articles/566448/WCF-Instance-Management it seems i am using the perSession mode, with fits perfectly).
* Everytime a client is closed, the deconstructor of the service-instance isn't called, so it seems it remains in memory.

My question is: how can these zombie-instances be disposed without closing the host? I want to keep it running for other clients.
Afzaal Ahmad Zeeshan 14-Apr-15 5:04am    
That is because you explicitly open the connection by using host.Open(), but you do not close the connection... Just the way connection is opened for every client, it should be closed for every client. Makes sense?

Also, I have added the solution, in which it is stated that Dispose function is called automatically. Please read the Solution 1.

1 solution

When you are using the using statement, all of the objects that can be used here (inside the using block) must implement the IDisposable[^] interface. So when you create the block, .NET framework automatically calls the Dispose() function and releases any resource attached to the variables and objects created (specially the one used in the using statement).

So in your code, host variable would get Dispose() called automatically, once the control hits the closing braces (}) of the code block. To give you an overview, your code is similar to this code,

C#
// Create new instance
var host = new ServiceHost(typeof (MyService), new Uri(cPar.conn));

// Use it as connection
host.AddServiceEndpoint(typeof (Itest), cPar.binding,"");
host.Open();
Console.WriteLine("Service running. Press ENTER to stop.");
Console.ReadLine();

// Cast to IDisposable and dispose
((IDisposable)host).Dispose();


The one thing that doesn't get performed is Close() automatically, which you have to call yourself to close the connection. Also, Dispose() does not call the destructor, it just releases the resources for other objects and methods to use; once object is disposed .NET framework would call the destructor[^] automatically, you should not call destructors. For more on this please read this MSDN resource about using statement[^] and all other resources attached.
 
Share this answer
 
Comments
Florian Braun 14-Apr-15 5:12am    
but isn't ((IDisposable)host).Dispose(); only called after a key is pressed? When the host is shut down?
Afzaal Ahmad Zeeshan 14-Apr-15 5:21am    
Nope, it is called when your control reaches the last line on the using statement; when your host is going out of scope. Host doesn't shut down. It either gets closed (for every client separately) or it goes out of scope. Dispose is a function that is implemented for objects that implement IDisposable interface.

Also, there is no key interaction required.
Florian Braun 14-Apr-15 5:29am    
is your line of code is inserted after Console.ReadLine() it is only reached after a key is pressed. The using block will be left and host gets disposed. When this happens all created instances of the service-object are destroyed. I will add some screenshots, maybe this helps to see what i mean.
Afzaal Ahmad Zeeshan 14-Apr-15 5:31am    
No that was the explanation of your code in simple C#; without using statement. If you remove that key line your host would still be disposed. All instances for current client are destroyed, not for all clients.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900