AppDomain上遇到的问题
一开始为了动态更新exe.config文件中的内容,想了一招,就是用AppDomain,创建一个AppDomain,然后load进来一个assembly,如果改变了就重新加载。
工作是很好的,可是发生了一件事。就是这个Form放置了一段时间后再操作,会有异常。
跟踪进去一看,发现是取formLogin的属性是出错,说是超时一类的。一开始以为是因为调用Web services的缘故,做了很多工作,还是徒然。
后来开始怀疑到AppDomain, 理解如下:
FormLogin是在MyDomain内创建的实例
那么formLogin在默认域内的实例实际上是MyDomain内实例的一个proxy
跟踪看到,果然是一个System.Runtime.Remoting.Proxies.__TransparentProxy对象
就想了一个土招
就是
在ShowDialog之前,得到租约,然后把这个租约传到FormLogin中,在FormLogin加一个Timer,检测到快超时的时候,就Renew租约。
System.Runtime.Remoting.Lifetime.ILease lease = (formLogin as MarshalByRefObject).InitializeLifetimeService() as System.Runtime.Remoting.Lifetime.ILease;
formLogin.Lease = lease;
本以为会有问题,可是居然成了。不过心里还是有些忐忑不安的。
AppDomain domain = AppDomain.CreateDomain("MyDomain", null, null);
System.Reflection.Assembly ass = System.Reflection.Assembly.LoadFrom(".\FormLogin.dll");
FormLogin formLogin = (FormLogin)domain.CreateInstanceAndUnwrap(ass.FullName, typeof(FormLogin).ToString());
DialogResult result = formLogin.ShowDialog();
if(result == DialogResult.OK)
{
FormMain.userName = formLogin.userName;
FormMain.userID = formLogin.userName + formLogin.cityCode;
FormMain.offlineFlag = formLogin.OfflineFlag;
try
{
Application.Run(new FormMain());
}
catch(Exception ex)
{
throw ex;
}
}
else if(result == DialogResult.Retry)
{
AppDomain.Unload(domain);
FormLogin formLogin2 = new FormLogin();
System.Reflection.Assembly ass = System.Reflection.Assembly.LoadFrom(".\FormLogin.dll");
FormLogin formLogin = (FormLogin)domain.CreateInstanceAndUnwrap(ass.FullName, typeof(FormLogin).ToString());
DialogResult result = formLogin.ShowDialog();
if(result == DialogResult.OK)
{
FormMain.userName = formLogin.userName;
FormMain.userID = formLogin.userName + formLogin.cityCode;
FormMain.offlineFlag = formLogin.OfflineFlag;
try
{
Application.Run(new FormMain());
}
catch(Exception ex)
{
throw ex;
}
}
else if(result == DialogResult.Retry)
{
AppDomain.Unload(domain);
FormLogin formLogin2 = new FormLogin();
工作是很好的,可是发生了一件事。就是这个Form放置了一段时间后再操作,会有异常。
跟踪进去一看,发现是取formLogin的属性是出错,说是超时一类的。一开始以为是因为调用Web services的缘故,做了很多工作,还是徒然。
后来开始怀疑到AppDomain, 理解如下:
FormLogin是在MyDomain内创建的实例
那么formLogin在默认域内的实例实际上是MyDomain内实例的一个proxy
跟踪看到,果然是一个System.Runtime.Remoting.Proxies.__TransparentProxy对象
就想了一个土招
就是
在ShowDialog之前,得到租约,然后把这个租约传到FormLogin中,在FormLogin加一个Timer,检测到快超时的时候,就Renew租约。
System.Runtime.Remoting.Lifetime.ILease lease = (formLogin as MarshalByRefObject).InitializeLifetimeService() as System.Runtime.Remoting.Lifetime.ILease;
formLogin.Lease = lease;
本以为会有问题,可是居然成了。不过心里还是有些忐忑不安的。