|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
不可能天天有学习.net),我一同学说,你应该早就有作品啦。我惶惶然……在我翻译的InfoQ旧事《WCF的成绩和Using语句块》中提到了开释客户端资本(个中包含端口、通道)和封闭毗连的成绩。旧事并没有很深切地会商,以是我想再增补一些内容。
毫无疑问,在.NETFramework中,一个资本(特别长短托管资本)一般都必要完成IDisposable接口。一旦完成了该接口,我们就能够利用using语句来办理资本,这是最便利的体例。可是,一旦在using语句中抛出了非常,便可能不会准确完成资本的接纳,特别是毗连,极可能会一向翻开,既占用了通道和端口,还大概呈现资本的华侈,从而影响体系的功能和不乱性。
微软保举的最好理论是丢弃using语句,转而使用try/catch(/finally)语句。它请求在try语句中挪用Close()办法,而在catch中挪用Abort()办法。在旧事中已申明了Close()与Abort()办法的区分,即后者能够强迫地封闭客户端,包含封闭客户端毗连,开释资本。因为Close()办法大概会抛出CommunicationException和TimeoutException非常,一般的客户端代码应当是如许:
varmyClient=newMyClient();
try
{
//其他代码
myClient.Close();
}
catch(CommunicationException)
{
myClient.Abort();
}
catch(TimeoutException)
{
myClient.Abort();
}
catch(Exception)
{
myClient.Abort();
throw;
}
在最初增添对Exception非常的捕捉很有需要,由于我们不晓得Close()办法会否抛出某些不成预知的非常,比方OutOfMemoryException等。旧事中提到SteveSmith的办法实在就是对这段冗杂代码的封装,封装体例是接纳扩大办法,扩大的范例为ICommunicationObject。这是由于一切的客户端对象都完成了ICommunicationObject接口。以下是SteveSmith的扩大办法代码:
publicstaticclassExtensions
{
publicstaticvoidCloseConnection(thisICommunicationObjectmyServiceClient)
{
if(myServiceClient.State!=CommunicationState.Opened)
{
return;
}
try
{
myServiceClient.Close();
}
catch(CommunicationExceptionex)
{
Debug.Print(ex.ToString());
myServiceClient.Abort();
}
catch(TimeoutExceptionex)
{
Debug.Print(ex.ToString());
myServiceClient.Abort();
}
catch(Exceptionex)
{
Debug.Print(ex.ToString());
myServiceClient.Abort();
throw;
}
}
}
使用该扩大办法,在本应挪用Close()办法的中央,取代为CloseConnection()办法,就能够制止写冗杂的catch代码。而利用Lambda表达式的体例能够说是独辟门路,利用起来与using语法大抵靠近。完成办法是界说一个静态办法,并承受一个ICommunicationObject对象与Action托付:
publicclassUtil
{
publicstaticvoidUsing<T>(Tclient,Actionaction)
whereT:ICommunicationObject
{
try
{
action(client);
client.Close();
}
catch(CommunicationException)
{
client.Abort();
}
catch(TimeoutException)
{
client.Abort();
}
catch(Exception)
{
client.Abort();
throw;
}
}
}
利用时,能够将底本的客户端代码作为Action托付的Lambda表达式传送给Using办法中:
Util.Using(newMyClient(),client=>
{
client.SomeWCFOperation();
//其他代码;
});
另有一种办法是界说一个本人的ChannelFactory,让实在现IDisposable接口,并作为ChannelFactory的Wrapper类。在该类中界说Close()和Dispose()办法时,思索到非常抛出的情形,并在非常抛出时挪用Abort()办法。如许我们就能够在using中利用自界说的ChannelFactory类。比方:
publicclassMyChannelFactory:IDisposable
{
privateChannelFactorym_innerFactory;
publicMyChannelFactory(ChannelFactoryfactory)
{
m_innerFactory=factory;
}
~MyChannelFactory()
{
Dispose(false);
}
publicvoidClose()
{
Close(TimeSpan.FromSeconds(10));
}
publicvoidClose(TimeSpanspan)
{
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;
}
}
}
privatevoidDispose(boolingdisposing)
{
if(disposing)
{
Close();
}
}
voidIDisposable.Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
实在,旧事中提到接纳代办署理形式的体例与此完成不异。总之,万变不离其宗,一切替换计划的计划实质都是对冗杂的try/catch/finally的一次包装,从而无效地完成重用,包管体系的平安、功能与不乱性。
以前很热炒跨平台,主要是由于硅谷挑战微软霸主地位的热情,但是冷静下来后,跨平台往往不是那么一回事。假设你有个软件,所谓的跨平台,你只需要为第二个平台上重新编译一次就行了,这样很难么? |
|