简体   繁体   中英

WCF Service Reference in ASP.net Page - When to Dispose?

I have an ASP.net page that is creating a service reference to a WCF service and making calls in multiple places in my page. I instantiate the service reference in Page_Load and have an instance variable to store it:

private FooClient _serviceClient;

protected void Page_Load(object sender, EventArgs e)
{
    _serviceClient = nwe FooClient();
    _serviceClient.GetAllFoos();
}

protected void btnSave_Click(object sender, EventArgs e)
{
    _serviceClient.SaveFoo();
}

I just discovered that I need to be disposing of the service reference when I am done using it or else the connections will be kept alive and will block incoming connections if I reach the max number of connections. Where would the best place to dispose of these references be? I was thinking of doing it on the OnUnLoad event.

Is there a better way of doing this?

Personally, I would open FooClient when I need it, so not in Page_Load but in the methods that do web service calls. This way, you know exactly what happens to it. I usually take the following approach:

var client = OpenClient();
try
{
    // Perform operation(s) on client.
}
finally
{
    CloseClient(client);
}

This way you are sure you close your proxy, whatever happens (if there are exceptions you need to catch, simply add a catch clause). The CloseClient method should look like the one in PaulStack's answer.

Another benefit you get when you do this is that multiple calls don't interfere with eachother. Suppose one of you web service calls leads to an unexpected exception. The client channel is now in a faulted state and therefore unusable for any other calls.

And third, suppose an exception does occur that you can not catch or do not want to catch, I'm not sure Page_Unload is actually called (and I don't know what page method will be called in that event). This will also leave connections open.

according to MSDN documentation and personal experience do something as follows:

 try
{
    ...
    client.Close();
}
catch (CommunicationException e)
{
    ...
    client.Abort();
}
catch (TimeoutException e)
{
    ...
    client.Abort();
}
catch (Exception e)
{
    ...
    client.Abort();
    throw;
}

this would allow the correct closing or abortion of the service when necessary rather than leaving them to be disposed at a predefined time - only keep the connection open as long as you definately have to. personally i dont like inheriting from IDisposable as its very heavy in performance

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