简体   繁体   中英

How to close a WCF Client connection

I'm new in WCF, just learning it so far. But I was wondering how to close a WCF client connection from the client side (if it is needed at all? I think so).

I have an interface called

[ServiceContract]
ICalculatorService { blabla... }

The question is on the client side. So far, I used the following format:

EndpointAddress epAddress = new EndpointAddress("http://localhost:8090/CalculatorService");
ICalculatorService calculatorProxy = ChannelFactory<ICalculatorService>.CreateChannel(new WSHttpBinding(), epAddress);

and now I can:

Result numeralResult = calculatorProxy.AddNumbers(4, 5);

and I got the result and I was happy.

Every single (for example) Button pressing caused the mentioned code to run once.

My question is: is the efficient?

Now I'm thinking of putting this into a separate class, for example:

class CalculatorProxy
{
    static EndpointAddress epAddress = new EndpointAddress("http://localhost:8090/CalculatorService");

    public static ChannelFactory<ICalculatorService> GetCalculatorProxy()
    {

    }

    public void Dispose() { ... }
}

... and use it like:

using (ICalculatorService calculatorClient = CalculatorProxy.GetCalculatorProxy())
{
    calculatorClient.AddNumbers(4, 4);                
}

which one would be more efficient?

UPDATE:

Thank you all for your answers.

I finally ended up with this class:

class CalculatorServiceClient : ClientBase<ICalculatorService>, IDisposable
{
    static EndpointAddress epAddress = new EndpointAddress("http://localhost:8090/CalculatorService");
    ICalculatorService myCalculatorProxy;

    public CalculatorServiceClient()
        : base(new WSHttpBinding(), epAddress)
    {
        myCalculatorProxy = ChannelFactory.CreateChannel();
    }

    public static CalculatorServiceClient GetNewInstance()
    {
        return new CalculatorServiceClient();
    }

    public Result AddNumbers(int aIn, int bIn)
    {
        return myCalculatorProxy.AddNumbers(aIn, bIn);
    }

    public void Dispose()
    {
        try
        {
            Close();
        }
        catch (CommunicationObjectFaultedException ex)
        {
            throw new DBCommunicationException("CalculatorServiceClient is in the Faulted state.", ex);
        }           
        catch (Exception ex)
        {
            throw new DBCommunicationException("Communication is unsuccessful between the CalculatorServiceClient and the CalculatorService.", ex);
        }
    }
}

And use it in this way:

try
{
    using (CalculatorServiceClient calculatorClient = CalculatorServiceClient.GetNewInstance())
    {
        Result aResult = calculatorClient.AddNUmbers(tbA.Text, tbB.Text);
    }
}
catch (DBCommunicationException ex)
{
    MessageBox.Show("Service is shut down.");
}

My question is: is this efficient?

You should just close the client when each operation you have done is completed and you don't need anymore to make other calls. When your work is finished, just close the client using the Close method:

calculatorProxy.Close();

About the Close() method, the MSDN documentation states:

This method causes a CommunicationObject to gracefully transition from any state, other than the Closed state, into the Closed state. The Close method allows any unfinished work to be completed before returning. For example, finish sending any buffered messages.

About your approach, I think the second one is fine and more efficient, because you're also implementing the Dispose pattern and release the used resources (this depends on the resources you're using). Just add the Close() method when the work is finished:

calculatorClient.AddNumbers(4, 4);
calculatorProxy.Close();

Remember also that there's no performance issue creating and closing continuously the WCF clients. This is just a normal habitude.

you can call the close method of your proxy class.

like

calculatorProxy.Close();

Alternatively you call the abort method on your service proxy class in case of exception.

 try
 {
       calculatorProxy.SomeMethod();
       calculatorProxy.Close();
 }
 catch
  {
       calculatorProxy.Abort();
   }

Refer to this link for further details

I think you would find it better to put all of that in a class. Establishing an instance of the class can construct the connection and close/dispose when the time comes. Until then, you have an open and active channel to make calls to.

using (var client = new CalculatorServiceClient())
{
    client.SomeMethod();
}

The CalculatorServiceClient object will be available once you add a Service Reference to your Calculator WebService to your client project.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM