3 Stimmen

WCF Verbindung schließen mit anonymen Methoden

In unserem Projekt führen wir WCF-Aufrufe mit folgendem Code durch.

// In generated Proxy we have..
public static ICustomer Customer
{
 get
  {
    ChannelFactory<ICustomer> factory = new ChannelFactory<ICustomer>("Customer");
    factory.Endpoint.Behaviors.Add((System.ServiceModel.Description.IEndpointBehavior)new ClientMessageInjector());
    ICustomer channel = factory.CreateChannel();
    return channel;
  }
}

und wir haben die Klasse Service Proxy, die die Methoden hat wie

public static Datatable GetCustomerDetails(int id)
{
  return Services.Customer.GetCustomerDetails(id);
} 

public static void .SaveCustomerDetails (int id)
{
  Services.Customer.SaveCustomerDetails(id) ;
}

usw., die wir für Geschäftsgespräche nutzen.

Kürzlich haben wir herausgefunden, dass wir die wcf-Verbindung "schließen" müssen, und wir versuchen herauszufinden, wie wir dies tun können, ohne dass unsere Entwickler zu viel an ihrem Code ändern müssen.

Bitte machen Sie uns einige Vorschläge, wie wir dieses Ziel erreichen können

6voto

marc_s Punkte 701497

Die anerkannte "beste Praxis" für diesen Fall wäre in etwa die folgende:

// create your client
ICustomer channel = CreateCustomerClient();

try
{
   // use it
   channel.GetCustomerDetails() ....

   (more calls)

   // close it
   channel.Close();
}
catch(CommunicationException commEx)
{
   // a CommunicationException probably indicates something went wrong 
   // when closing the channel --> abort it
   channel.Abort();
}

Da der Kanal auch "IDisposable" implementiert, könnte man versucht sein, ihn einfach in eine

using(ICustomer channel = CreateCustomerChannel()) 
{
   // use it
}

blockieren - leider könnte das in die Hose gehen, da die Wahrscheinlichkeit groß ist, dass Sie beim Versuch, .Close() auf Ihrem Kanal aufzurufen, eine weitere Ausnahme erhalten (die in diesem Fall unbehandelt bleiben würde).

Unser Moderator hier, Marc Gravell, hat eine interessante Blog-Beitrag (nicht(nicht(verwenden)) zu diesem Thema mit einer eleganten Lösung für dieses Problem.

Marc

1voto

bobbymcr Punkte 23043

Sie sind auch undicht ChannelFactory<T> Objekte im aktuellen Ansatz. Auch diese sollten Sie schließen. Wenn Sie das statische CreateChannel Methoden zu ChannelFactory<T> erhalten Sie ein automatisches Schließverhalten für die Fabrik, wenn der Client geschlossen wird, so dass dieses Problem gelöst werden könnte. Leider ist die statische CreateChannel(string endpointConfigurationName) Überladung ist geschützt, also müssen Sie die Unterklasse ChannelFactory<T> um sie aufzurufen. (Das könnte insgesamt gar nicht so schlecht sein.)

Wenn Sie nun das "Auto-Close"-Verhalten eines Kanals wünschen und einen sitzungsbezogenen Vertrag verwenden ( SessionMode = SessionMode.Required ), können Sie alle Ihre Dienstvorgänge mit " IsInitiating = true, IsTerminating = true " in der [OperationContract] Attribut. Beachten Sie, dass Sie damit verhindern, dass Sie mehr als eine Operation mit demselben ICustomer-Proxy aufrufen können. Dies könnte die einfachste Option sein, wenn sie Ihnen zur Verfügung steht.

Was Ihren allgemeinen Ansatz betrifft, so gilt es nicht als gutes Design, wenn eine Eigenschaft zu viel Arbeit macht, vor allem, wenn sie die Konstruktion neuer (teurer) Objekte und die Belastung des Netzes mit sich bringt. WCF-Proxies sind nette Abstraktionen und sehen aus wie einfache Schnittstellenimplementierungen, aber sie sind nicht zustandslos und müssen entsprechend verwaltet werden.

0voto

Steven Sudit Punkte 19005

Die richtige Art und Weise, Verbindungen zu schließen, besteht darin, den Client in einen using-Block zu setzen, oder das Schließen in ein finally zu setzen. Andernfalls werden sie nur geschlossen, wenn keine Ausnahme geworfen wird.

0voto

Eric King Punkte 11152

Die Informationen in dieser Frage kann ebenfalls hilfreich sein.

0voto

Leider verwenden wir die generierten Proxy-Methoden, die den Kanal zurückgibt, und wir verwenden es an vielen Stellen, so dass ich dachte, es wäre eine Möglichkeit, "erweitern" den Kanal und schließen Sie die Verbindung nach dem Aufruf (mit Erweiterung Methoden).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X