I've set up a WCF NamedPipes Server/Client pair of applications but when the Host stops and calls ServiceHost.Close()
it doesn't seem to appropriately cleanup the object from which the Host was created (using an object rather than a type to instantiate the host).
The server application code is as follows:
static void Main(string[] args) {
// Specify the device type. Consider command line arguments here.
DeviceTypes deviceType = DeviceTypes.myDeviceType;
// Create the service object.
ServiceHost selfHost = ServiceFactory.CreateService(deviceType);
try {
// Start the service.
selfHost.Open();
System.Console.WriteLine("The service is ready.");
System.Console.WriteLine("Press <ENTER> to terminate service.");
System.Console.WriteLine();
System.Console.ReadLine();
// Stop the service.
System.Console.WriteLine("Closing the service.");
selfHost.Close();
} catch (CommunicationException e) {
System.Console.WriteLine("An exception occurred: {0}", e.Message);
selfHost.Abort();
}
}
The ServiceFactory.CreateService
method:
public static ServiceHost CreateService(DeviceTypes type) {
// Create the client object.
// Create_Server only creates an uninitialized child class based on the type.
IMyServer client = MyServerFactory.Create_Server(type);
// Initialize the client.
client.Initialize();
// Create the service object.
MyService server = new MyService(client);
// Create a service host.
ServiceHost selfHost = new ServiceHost(server, new System.Uri(baseAddress));
// Add a service endpoint.
selfHost.AddServiceEndpoint(typeof(IMyActions), new NetNamedPipeBinding(), relAddress);
return selfHost;
}
The MyService
class (which contains the resource I want to clean up):
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode =
InstanceContextMode.Single)]
class MyService : IMyActions
{
private IMyServer server;
public MyService(IMyServer server) {
this.server = server;
}
// Bunch of public operations to carry out the contract
public bool Initialize() {
return server.Initialize();
}
public void Dispose() {
server.Dispose();
}
// No-op to check pipe connection.
public void ConfirmConnection() { }
}
How and where should I call the server.Dispose()
method in the MyService
class?
I thought that this would be handled by selfHost.Close()
but it seems not...
Your output is a ServiceHost
which is not a custom type you create.
Therefore it will not automatically call IMyServer.Dispose()
.
Instead of returning a ServiceHost
, create some kind of adapter that will manage the ServiceHost
and your IMyServer
instance and return it to the void Main()
method.
Then, simply add a finally clause (or implement IDisposable
and use using
) and call your adapter's dispose, that will call serviceHost.Dispose()
and myServer.Dispose()
.