Где я должен очистить частные ресурсы для ServiceHost? - PullRequest
0 голосов
/ 30 апреля 2020

Я настроил пару приложений WCF NamedPipes Server / Client, но когда Хост останавливается и вызывает ServiceHost.Close(), кажется, что он не очищает должным образом объект, из которого был создан Хост (используя объект вместо введите экземпляр хоста).

Код серверного приложения выглядит следующим образом:

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();
  }
}

Метод ServiceFactory.CreateService:

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;
}

Класс MyService (который содержит ресурс, который я хочу очистить):

[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() { }
}

Как и где я должен вызвать метод server.Dispose() в классе MyService? Я думал, что это будет обработано selfHost.Close(), но, похоже, нет ...

1 Ответ

1 голос
/ 30 апреля 2020

Ваш вывод - ServiceHost, который не является пользовательским типом, который вы создаете. Поэтому он не будет автоматически вызывать IMyServer.Dispose().

Вместо того, чтобы возвращать ServiceHost, создайте какой-то адаптер, который будет управлять ServiceHost и вашим IMyServer экземпляром и вернуть его в void Main() method.

Затем просто добавьте предложение finally (или реализуйте IDisposable и используйте using) и вызовите утилиту вашего адаптера, которая вызовет serviceHost.Dispose() и myServer.Dispose().

...