Dispose in WCF

Source: Internet
Author: User

In my translated InfoQ News "issues with WCF and Using statement blocks", I mentioned the issue of releasing client resources (including ports and channels) and closing connections. The news is not discussed in depth, so I want to add more content.

No
No doubt, in. NET
Framework, a resource (especially an unmanaged Resource) usually needs to implement the IDisposable interface. Once this interface is implemented, we can use the using statement to manage
Resources, which is the most convenient way. However, once an exception is thrown in the using statement, the resource recovery may not be completed correctly, especially the connection, which may be opened all the time, occupying both the channel and port,
There may also be a waste of resources, thus affecting system performance and stability.

The best practice recommended by Microsoft is to abandon using statements and use them in turn.
Try/catch (/finally) statement. It requires that the Close () method be called in the try statement, and the Abort () method be called in the catch statement. It has been stated in the news
The difference between the Close () and Abort () methods is that the latter can forcibly Close the client, including closing the client connection and releasing resources. The Close () method may throw
CommunicationException and TimeoutException exceptions. The common client code is as follows:
Var myClient = new MyClient ();
Try
{
// Other code
MyClient. Close ();
}
Catch (CommunicationException)
{
MyClient. Abort ();
}
Catch (TimeoutException)
{
MyClient. Abort ();
}
Catch (Exception)
{
MyClient. Abort ();
Throw;
}

In
Finally, it is necessary to add a catch to the Exception because we do not know whether the Close () method will throw some unpredictable exceptions, such
OutOfMemoryException. Steve mentioned in the news
Smith's method is actually an encapsulation of this lengthy code. The encapsulation method is an extension method, and the extension type is ICommunicationObject. This is because all clients
All objects implement the ICommunicationObject interface. The following is the extended method code of Steve Smith:
Public static class Extensions
{
Public static void CloseConnection (this ICommunicationObject myServiceClient)
{
If (myServiceClient. State! = CommunicationState. Opened)
{
Return;
}
Try
{
MyServiceClient. Close ();
}
Catch (CommunicationException ex)
{
Debug. Print (ex. ToString ());
MyServiceClient. Abort ();
}
Catch (TimeoutException ex)
{
Debug. Print (ex. ToString ());
MyServiceClient. Abort ();
}
Catch (Exception ex)
{
Debug. Print (ex. ToString ());
MyServiceClient. Abort ();
Throw;
}
}
}

Benefit
This extension method can be used to replace the CloseConnection () method in the place where the Close () method should be called to avoid lengthy catch code writing. And use
Lambda expressions are used in a similar way to the using syntax. The implementation method is to define a static method and accept
ICommunicationObject object and Action delegate:
Public class Util
{
Public static void Using <T> (T client, Action action)
Where T: ICommunicationObject
{
Try
{
Action (client );
Client. Close ();
}
Catch (CommunicationException)
{
Client. Abort ();
}
Catch (TimeoutException)
{
Client. Abort ();
}
Catch (Exception)
{
Client. Abort ();
Throw;
}
}
}

In use, the original client code can be passed to the Using method as the Lambda expression entrusted by the Action:
Util. Using (new MyClient (), client =>
{
Client. SomeWCFOperation ();
// Other code;
});

Also
One way is to define a ChannelFactory to implement the IDisposable interface and use it as the Wrapper of ChannelFactory.
Class. When defining the Close () and Dispose () methods in this class, the Abort () method is called when the exception is thrown and the exception is thrown. In this way, we can
Use the custom ChannelFactory class. For example:
Public class MyChannelFactory: IDisposable
{
Private ChannelFactory m_innerFactory;
Public MyChannelFactory (ChannelFactory factory)
{
M_innerFactory = factory;
}
~ MyChannelFactory ()
{
Dispose (false );
}
Public void Close ()
{
Close (TimeSpan. FromSeconds (10 ));
}
Public void Close (TimeSpan span)
{
If (m_innerFactory! = Null)
{
If (m_innerFactory.State! = CommunicationState. Opened)
{
Return;
}
Try
{
M_innerFactory.Close (span );
}
Catch (CommunicationException)
{
M_innerFactory.Abort ();
}
Catch (TimeOutException)
{
M_innerFactory.Abort ();
}
Catch (Exception)
{
M_innerFactory.Abort ();
Throw;
}
}
}
Private void Dispose (booling disposing)
{
If (disposing)
{
Close ();
}
}
Void IDisposable. Dispose ()
{
Dispose (true );
GC. SuppressFinalize (this );
}
}

In fact, we mentioned in the news that the proxy mode is the same. In short, the design of all alternative solutions is essentially a lengthy try/catch/finally packaging, so as to effectively achieve reuse and ensure the security, performance and stability of the system.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.