表示应用程序域,它是一个应用程序在其中执行的独立环境。
创建新的 AppDomain,在该新建 AppDomain 中实例化类型,以及与该类型的对象通信。
using nbsp;System.Reflection;
using nbsp;System.Threading;
class nbsp;Module1
{
nbsp;nbsp;nbsp;nbsp; public nbsp; static nbsp; void nbsp;Main()
nbsp;nbsp;nbsp;nbsp;{
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; // nbsp;得到应用程序域名称nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; string nbsp;callingDomainNamenbsp; = nbsp;Thread.GetDomain().FriendlyName;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;Console.WriteLine(callingDomainName);
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; // nbsp;得到应用程序域全名
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; string nbsp;exeAssemblynbsp; = nbsp;Assembly.GetEntryAssembly().FullName;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;Console.WriteLine(exeAssembly);
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; // nbsp;构造一个新的应用程序域
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;AppDomainSetupnbsp;adsnbsp; = nbsp; new nbsp;AppDomainSetup();
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;ads.ApplicationBasenbsp; = nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; " file:/// " nbsp; + nbsp;System.Environment.CurrentDirectory;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;ads.DisallowBindingRedirectsnbsp; = nbsp; false ;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;ads.DisallowCodeDownloadnbsp; = nbsp; true ;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;ads.ConfigurationFilenbsp; = nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; // nbsp;创建应用程序域
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;AppDomainnbsp;ad2nbsp; = nbsp;AppDomain.CreateDomain( " ADnbsp;#2 " ,nbsp; null ,nbsp;ads);
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;MarshalByRefTypenbsp;mbrtnbsp; = nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;(MarshalByRefType)nbsp;ad2.CreateInstanceAndUnwrap(
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;exeAssembly,nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; typeof (MarshalByRefType).FullName
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;);
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;mbrt.SomeMethod(callingDomainName);
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;AppDomain.Unload(ad2);
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; try
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;{
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;mbrt.SomeMethod(callingDomainName);
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;Console.WriteLine( " Sucessfulnbsp;call. " );
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;}
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; catch (AppDomainUnloadedException)
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;{
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;Console.WriteLine( " Failednbsp;call;nbsp;thisnbsp;isnbsp;expected. " );
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;}
nbsp;nbsp;nbsp;nbsp;}
}
public nbsp; class nbsp;MarshalByRefTypenbsp;:nbsp;MarshalByRefObject
{
nbsp;nbsp;nbsp;nbsp; public nbsp; void nbsp;SomeMethod( string nbsp;callingDomainName)
nbsp;nbsp;nbsp;nbsp;{
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;AppDomainSetupnbsp;adsnbsp; = nbsp;AppDomain.CurrentDomain.SetupInformation;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;Console.WriteLine( " AppName={0},nbsp;AppBase={1},nbsp;ConfigFile={2} " ,nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;ads.ApplicationName,nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;ads.ApplicationBase,nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;ads.ConfigurationFile
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;);
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;Console.WriteLine( " Callingnbsp;fromnbsp;'{0}'nbsp;tonbsp;'{1}'. " ,nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;callingDomainName,nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;Thread.GetDomain().FriendlyName
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;);
nbsp;nbsp;nbsp;nbsp;}
}
/* nbsp;Thisnbsp;codenbsp;producesnbsp;outputnbsp;similarnbsp;tonbsp;thenbsp;following:nbsp;
AppDomainX.exe
AppDomainX,nbsp;Version=1.0.0.0,nbsp;Culture=neutral,nbsp;PublicKeyToken=null
AppName=,nbsp;AppBase=C:\AppDomain\bin,nbsp;ConfigFile=C:\AppDomain\bin\AppDomainX.exe.config
Callingnbsp;fromnbsp;'AppDomainX.exe'nbsp;tonbsp;'ADnbsp;#2'.
Failednbsp;call;nbsp;thisnbsp;isnbsp;expected.
nbsp; */
nbsp;
nbsp;
nbsp;
public nbsp; class nbsp;MyType
{
nbsp;nbsp;nbsp; public nbsp; int nbsp;i;
}
// 传递数据
public nbsp; class nbsp;Program
{
nbsp;nbsp;nbsp; public nbsp; static nbsp; void nbsp;Test()
nbsp;nbsp;nbsp;{
nbsp;nbsp;nbsp;nbsp;nbsp;AppDomainnbsp;domainnbsp; = nbsp;AppDomain.CurrentDomain;
nbsp;nbsp;nbsp;nbsp;nbsp;MyTypenbsp;tnbsp; = nbsp;domain.GetData( " arg " )nbsp; as nbsp;MyType;
nbsp;nbsp;nbsp;nbsp;nbsp;Console.WriteLine( " [{0}]nbsp;{1} " ,nbsp;domain.FriendlyName,nbsp;t.i);
nbsp;nbsp;nbsp;nbsp;nbsp; if nbsp;(domain.FriendlyNamenbsp; == nbsp; " NewDomain " )nbsp;t.inbsp; = nbsp; 1000000000 ;
nbsp;nbsp;nbsp;}
nbsp;nbsp;nbsp; static nbsp; void nbsp;Main()
nbsp;nbsp;nbsp;{
nbsp;nbsp;nbsp;nbsp;nbsp;AppDomainnbsp;ndomainnbsp; = nbsp;AppDomain.CreateDomain( " NewDomain " );
nbsp;nbsp;nbsp;nbsp;nbsp;MyTypenbsp;tnbsp; = nbsp; new nbsp;MyType();nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp;AppDomain.CurrentDomain.SetData( " arg " ,nbsp;t);
nbsp;nbsp;nbsp;nbsp;nbsp;ndomain.SetData( " arg " ,nbsp;t);
nbsp;nbsp;nbsp;nbsp;nbsp;t.inbsp; = nbsp; 13 ;
nbsp;nbsp;nbsp;nbsp;nbsp;Test();
nbsp;nbsp;nbsp;nbsp;nbsp;ndomain.DoCallBack( new nbsp;CrossAppDomainDelegate(Test));
nbsp;nbsp;nbsp;nbsp;nbsp;Test();
nbsp;nbsp;nbsp;}
}
nbsp;
nbsp;
远程对象调用
{
nbsp;nbsp;nbsp; public nbsp; int nbsp;i;
}
public nbsp; class nbsp;Program
{
nbsp;nbsp;nbsp; public nbsp; static nbsp; void nbsp;Test()
nbsp;nbsp;nbsp;{
nbsp;nbsp;nbsp;nbsp;nbsp;AppDomainnbsp;domainnbsp; = nbsp;AppDomain.CurrentDomain;
nbsp;nbsp;nbsp;nbsp;nbsp;MyTypenbsp;tnbsp; = nbsp;domain.GetData( " arg " )nbsp; as nbsp;MyType;
nbsp;nbsp;nbsp;nbsp;nbsp;Console.WriteLine( " [{0}]nbsp;{1} " ,nbsp;domain.FriendlyName,nbsp;t.i);
nbsp;nbsp;nbsp;nbsp;nbsp; if nbsp;(domain.FriendlyNamenbsp; == nbsp; " NewDomain " )nbsp;t.inbsp; = nbsp; 1000000000 ;
nbsp;nbsp;nbsp;}
nbsp;nbsp;nbsp; static nbsp; void nbsp;Main()
nbsp;nbsp;nbsp;{
nbsp;nbsp;nbsp;nbsp;nbsp;AppDomainnbsp;ndomainnbsp; = nbsp;AppDomain.CreateDomain( " NewDomain " );
nbsp;nbsp;nbsp;nbsp;nbsp;MyTypenbsp;tnbsp; = nbsp; new nbsp;MyType();nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp; // nbsp;或者使用下列代码在ndomain上创建MyType对象。
nbsp;nbsp;nbsp;nbsp;nbsp; // nbsp;stringnbsp;assemblyNamenbsp;=nbsp;Assembly.GetExecutingAssembly().FullName;
nbsp;nbsp;nbsp;nbsp;nbsp; // nbsp;stringnbsp;typeNamenbsp;=nbsp;typeof(MyType).FullName;
nbsp;nbsp;nbsp;nbsp;nbsp; // nbsp;MyTypenbsp;tnbsp;=nbsp;ndomain.CreateInstanceAndUnwrap(assemblyName,nbsp;typeName)nbsp;asnbsp;MyType;nbsp;
nbsp;nbsp;nbsp;nbsp;nbsp;AppDomain.CurrentDomain.SetData( " arg " ,nbsp;t);
nbsp;nbsp;nbsp;nbsp;nbsp;ndomain.SetData( " arg " ,nbsp;t);
nbsp;nbsp;nbsp;nbsp;nbsp;t.inbsp; = nbsp; 13 ;
nbsp;nbsp;nbsp;nbsp;nbsp;Test();
nbsp;nbsp;nbsp;nbsp;nbsp;ndomain.DoCallBack( new nbsp;CrossAppDomainDelegate(Test));
nbsp;nbsp;nbsp;nbsp;nbsp;Test();
nbsp;nbsp;nbsp;}
}
nbsp;
nbsp;如果您使用的是一次性调用,上面的代码一点问题也没有,不过要是你使用的是生命周期比较长的对象,如这个远程对象要永久保持的,以便应用程序域之间进行不间断的调用,这种情况下生命周期的问题就出现,因为对象在应用程序域中调用是远程对象调用,对象的生命周期只有5分钟,过了之后,对象就会被垃圾回收机制强制回收.于是应用程序域之间的操作就被间断.
nbsp;nbsp;nbsp; 经过测试,直接使用延长生命周期的方法是最容易的.
nbsp;nbsp;nbsp; 1,客户端获取远程对象
nbsp;nbsp;nbsp; 两个应用服务器中,获取另一个应用程序域的对象中,此应用程序域被当成是客户端.需要使用RemotingServices.GetLifetimeService方法来获取远程对象.
nbsp;nbsp;nbsp; 2,延长生命周期
nbsp;nbsp;nbsp; 使用ILease.Renew来延长对象的生命周期,如直接延长3650天.
nbsp;nbsp;nbsp; 注意:
nbsp;nbsp;nbsp; 使用重写InitializeLifetimeService来延长生命周期的方法在这里不能使用.因为对象在创建的时间根本不可能是远程对象.
nbsp;nbsp;nbsp; 同样,如果您在处理Event时,也会存在生命周期的问题,了解上述的情况可以帮助您更好地解决应用程序域之间的持久交互的问题.
nbsp;
nbsp;