认识AppDomain类

表示应用程序域,它是一个应用程序在其中执行的独立环境。

创建新的 AppDomain,在该新建 AppDomain 中实例化类型,以及与该类型的对象通信。

using  System;
using  System.Reflection;
using  System.Threading;

class  Module1
{
    
public   static   void  Main()
    {
        
//  得到应用程序域名称 
         string  callingDomainName  =  Thread.GetDomain().FriendlyName;
        Console.WriteLine(callingDomainName);

        
//  得到应用程序域全名
         string  exeAssembly  =  Assembly.GetEntryAssembly().FullName;
        Console.WriteLine(exeAssembly);

        
//  构造一个新的应用程序域
        AppDomainSetup ads  =   new  AppDomainSetup();
        ads.ApplicationBase 
=  
            
" file:/// "   +  System.Environment.CurrentDirectory;
        ads.DisallowBindingRedirects 
=   false ;
        ads.DisallowCodeDownload 
=   true ;
        ads.ConfigurationFile 
=  
            AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;

        
//  创建应用程序域
        AppDomain ad2  =  AppDomain.CreateDomain( " AD #2 " null , ads);
       
        MarshalByRefType mbrt 
=  
            (MarshalByRefType) ad2.CreateInstanceAndUnwrap(
                exeAssembly, 
                
typeof (MarshalByRefType).FullName
            );

        mbrt.SomeMethod(callingDomainName);

        AppDomain.Unload(ad2);
        
try
        {
            mbrt.SomeMethod(callingDomainName);
            Console.WriteLine(
" Sucessful call. " );
        }
        
catch (AppDomainUnloadedException)
        {
            Console.WriteLine(
" Failed call; this is expected. " );
        }
    }
}

public   class  MarshalByRefType : MarshalByRefObject
{
    
public   void  SomeMethod( string  callingDomainName)
    {
        AppDomainSetup ads 
=  AppDomain.CurrentDomain.SetupInformation;
        Console.WriteLine(
" AppName={0}, AppBase={1}, ConfigFile={2} "
            ads.ApplicationName, 
            ads.ApplicationBase, 
            ads.ConfigurationFile
        );

        Console.WriteLine(
" Calling from '{0}' to '{1}'. "
            callingDomainName, 
            Thread.GetDomain().FriendlyName
        );
    }
}

/*  This code produces output similar to the following: 

AppDomainX.exe
AppDomainX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
AppName=, AppBase=C:\AppDomain\bin, ConfigFile=C:\AppDomain\bin\AppDomainX.exe.config
Calling from 'AppDomainX.exe' to 'AD #2'.
Failed call; this is expected.
 
*/

 

 

 

[Serializable]
public   class  MyType
{
   
public   int  i;
}
// 传递数据
public   class  Program
{
   
public   static   void  Test()
   {
     AppDomain domain 
=  AppDomain.CurrentDomain;
     MyType t 
=  domain.GetData( " arg " as  MyType;

     Console.WriteLine(
" [{0}] {1} " , domain.FriendlyName, t.i);
     
if  (domain.FriendlyName  ==   " NewDomain " ) t.i  =   1000000000 ;
   }

   
static   void  Main()
   {
     AppDomain ndomain 
=  AppDomain.CreateDomain( " NewDomain " );
     MyType t 
=   new  MyType(); 

     AppDomain.CurrentDomain.SetData(
" arg " , t);
     ndomain.SetData(
" arg " , t);

     t.i 
=   13 ;
     Test();
     ndomain.DoCallBack(
new  CrossAppDomainDelegate(Test));
     Test();
   }
}


 

 

远程对象调用

public   class  MyType: MarshalByRefObject 
{
   
public   int  i;
}

public   class  Program
{
   
public   static   void  Test()
   {
     AppDomain domain 
=  AppDomain.CurrentDomain;
     MyType t 
=  domain.GetData( " arg " as  MyType;

     Console.WriteLine(
" [{0}] {1} " , domain.FriendlyName, t.i);
     
if  (domain.FriendlyName  ==   " NewDomain " ) t.i  =   1000000000 ;
   }

   
static   void  Main()
   {
     AppDomain ndomain 
=  AppDomain.CreateDomain( " NewDomain " );
     MyType t 
=   new  MyType(); 

     
//  或者使用下列代码在ndomain上创建MyType对象。
     
//  string assemblyName = Assembly.GetExecutingAssembly().FullName;
     
//  string typeName = typeof(MyType).FullName;
     
//  MyType t = ndomain.CreateInstanceAndUnwrap(assemblyName, typeName) as MyType; 

     AppDomain.CurrentDomain.SetData(
" arg " , t);
     ndomain.SetData(
" arg " , t);

     t.i 
=   13 ;
     Test();
     ndomain.DoCallBack(
new  CrossAppDomainDelegate(Test));
     Test();
   }
}


 

 如果您使用的是一次性调用,上面的代码一点问题也没有,不过要是你使用的是生命周期比较长的对象,如这个远程对象要永久保持的,以便应用程序域之间进行不间断的调用,这种情况下生命周期的问题就出现,因为对象在应用程序域中调用是远程对象调用,对象的生命周期只有5分钟,过了之后,对象就会被垃圾回收机制强制回收.于是应用程序域之间的操作就被间断.
    经过测试,直接使用延长生命周期的方法是最容易的.
    1,客户端获取远程对象
    两个应用服务器中,获取另一个应用程序域的对象中,此应用程序域被当成是客户端.需要使用RemotingServices.GetLifetimeService方法来获取远程对象.
    2,延长生命周期
    使用ILease.Renew来延长对象的生命周期,如直接延长3650天.
    注意:
    使用重写InitializeLifetimeService来延长生命周期的方法在这里不能使用.因为对象在创建的时间根本不可能是远程对象.

    同样,如果您在处理Event时,也会存在生命周期的问题,了解上述的情况可以帮助您更好地解决应用程序域之间的持久交互的问题.

 

 

转载于:https://www.cnblogs.com/chenqingwei/archive/2010/04/30/1724892.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值