I didn't find this problem when I was just learning about WCF. I was very happy but didn't find that the "hidden hacker" was actually dangerous. Fortunately, later I thought it was inappropriate, as a result, Google "Do You Need To close WCF?" immediately found links to several blog parks. After reading them, all heroes said, "The customs must be closed, but you can't close it if you don't use it, because you can't open it again, and you have to use new. The cost of new is a little higher. "okay, in this case, you have to make a good plan.
So when should we close it? The answer is, when the exception occurs, msdn givesCode(The Error Handling Section cannot find the link. Sorry)
catch (communicationexception)
{< br> client. abort ();
}< br> catch (timeoutexception)
{< br> clent. abort ();
}< br>
, there is a solution, that is, add try catch in every place that requires calling WCF and code, which is probably like this
Userclient Client = New Userclient ();
Try
{
Client. Create ( New User (){
Username = " Xian " ,
Password = " 123 " });
} Catch(Communicationexception)
{
Client. Abort ();
}
Catch(Timeoutexception)
{
Clent. Abort ();
}
This is quite good, right, but we cannot just call one WCF interface. We need to call a series of interfaces, that is, several interfaces, then we need to write a lot of repeated error handling code blocks. In this way, there is no problem, and it is a matter of course. However, I remember an old bird said that you should refactor the code when the code is repeated to a large extent (it was also seen in the blog Park, which is common but deeply rooted in the hearts of the people ), in order to make the Code look better, we still need to think about a better way.
If you have some experience, you must immediately think of using delegation to eliminate code redundancy. Yes, the following is my implementation method. The Code is as follows:
{
Cnblogs_code_show ('161301a2-848c-4e6d-8285-e753464b552e ')
} "> {
Cnblogs_code_hide ('161301a2-848c-4e6d-8285-e753464b552e ', event)
} "Src =" http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif "alt =" "> Serviceinvokehelper calls the helper class
Using System;
Using System. Collections. Generic;
Using System. LINQ;
Using System. text;
Using System. servicemodel;
Namespace Helper
{
/// <Summary>
/// WCF Service call helper class
/// </Summary
Public static class serviceinvokehelper <Tchannel> Where tchannel: icommunicationobject, new ()
{
# Region Private Fields
Private Static Dictionary < String , Tchannel > _ Channeldic = New Dictionary < String , Tchannel > ();
Private Static Object _ Lockhelper = New Object ();
Private Static Tresult tryfunc < Tresult > (Func < Tchannel, tresult > Func, tchannel channel)
{
String Tchannelname = Typeof (Tchannel). fullname;
Try
{
Return Func (Channel );
}
Catch (Communicationexception)
{
Channel. Abort ();
Lock (_ Lockhelper)
_ Channeldic. Remove (tchannelname );
Throw ;
}
Catch (Timeoutexception)
{
Channel. Abort ();
Lock (_ Lockhelper)
_ Channeldic. Remove (tchannelname );
Throw ;
}
Catch (Exception)
{
Channel. Abort ();
Lock (_ Lockhelper)
_ Channeldic. Remove (tchannelname );
Throw ;
}
}
Private Static Tchannel getchannel ()
{
Tchannel instance;
String Tchannelname = Typeof (Tchannel). fullname;
If ( ! _ Channeldic. containskey (tchannelname ))
{
Lock (_ Lockhelper)
{
Instance = Activator. createinstance < Tchannel > ();
_ Channeldic. Add (tchannelname, instance );
}
}
Else
{
Instance = _ Channeldic [tchannelname];
}
If (Instance. State ! = Communicationstate. Opened && Instance. State ! = Communicationstate. Opening)
Instance. open ();
Return Instance;
}
/// <Summary>
/// Direct call with no return value
/// </Summary>
Public Static Void Invoke (Action < Tchannel > Action)
{
Tchannel instance = Getchannel ();
Tryfunc (
Client =>
{
Action (client );
Return ( Object ) Null ;
}
, Instance );
}
/// <Summary>
/// Calls with return values
/// </Summary>
Public Static Tresult invoke < Tresult > (Func < Tchannel, tresult > Func)
{
Tchannel instance = Getchannel ();
Icommunicationobject Channel = Instance As Icommunicationobject;
Tresult returnvalue = Default (Tresult );
Returnvalue = Tryfunc (func, instance );
Return Returnvalue;
}
}
}
With the above code, we can call the WCF
Serviceinvokehelper < Userclient > . Invoke (Client => Client. Create ({ New User {
Username = " Xian " ;
Password = " 123 " ;
}}));
During the test, it is found that the out and ref parameters are not supported. For example, this is not acceptable.
Public Void Getuserlist ( Int Pageindex, Int Pagesize, Ref Count)
{
Return Serviceinvokehelper < Userclient > . Invoke (Client => Client. getuserlist (pageindex, pagesize, Ref Count ));
}
But we can change it to the following:
Public Void Getuserlist ( Int Pageindex, Int Pagesize, Ref Count)
{
Return Serviceinvokehelper < Userclient > . Invoke (Client => { Int tmpcount =-1; Client. getuserlist (pageindex, pagesize, Ref Tmpcount )); Count = tmpcount; }
}