public interface ITemplate_DataChanger
{
event EventHandler<CurValueChangedArgs> CurValueChanged;
void myChangeMethod(string sPointName, object o);
}
类:
实现该接口, 并且在类中,有一个 BackgroundWorker , 在类的方法 myChangeMethod 中, 执行
BackgroundWorker.RunWorkerAsync(), 开始一个无限的循环,计算一些数据.
通过反射创建类实例
public ITemplate_DataChanger GetSelfDefInst(string sClsName, string sCode, object objPara)
{
string sClassName = sClsName;
ITemplate_DataChanger obj = null;
Assembly asm = null;
CompilerResults cr = ClsCodeCompiler.ComPile(sCode, false); // 动态编译代码,
if (cr.Errors.HasErrors)
return null;
try
{
asm = cr.CompiledAssembly;
obj = (ITemplate_DataChanger)asm.CreateInstance(sClassName, false, BindingFlags.Default, null, objPara, null, null);
return obj;
}
catch (Exception err)
{
Console.WriteLine(err.Message);
return null;
}
}
然后通过接口调用类中的方法
ITemplate_DataChanger ITest = GetSelfDefInst(.....);
ITest.myChangeMethod();
现在有一个很急的问题, 就是我怎样能够释放掉ITest ,以至于重新为ITest 赋值以后, 以前的线程能够被释放/终止..
34 个解决方案
#1
学习下!不明白
#2
交给.Net的垃圾回收机制
释放Assembly的资源AppDomain.Unload 方法
释放Assembly的资源AppDomain.Unload 方法
#3
1.如果你想保持你一直都只有一个实例对象的话,那么你可以使用单键(或者叫单例)模式来实现,比如:
C#实现Singleton的两种方法的比较
2.如果不是第1种情况,你想知道是否放掉了你实例,那么你的可以实现实现IDisposable接口.
析构函数、finalize、dispose、close的区别以及using()的用
C#实现Singleton的两种方法的比较
2.如果不是第1种情况,你想知道是否放掉了你实例,那么你的可以实现实现IDisposable接口.
析构函数、finalize、dispose、close的区别以及using()的用
#4
可是我是在当前域中,创建的Assembly.....请问能再讲细一吗??
应该怎样使用 AppDomain.Unload 呢?? 谢谢
#5
支持 实现实现IDisposable接口
#6
请问一下, 通过反射创建的实例, 这种方法好使吗??
#7
除了你将当前域给卸载了,这点MSDN中说的很清楚,反射加载的不能单载卸载某个类
如果你要能卸载程序集的话,单独创建一个域,用完后卸载域就行了
#10
亲爱的美羊羊童鞋,以及如梦哥和其他高手:
我现在重新创建一个程序域, 用于管理这些程序集
我现在重新创建一个程序域, 用于管理这些程序集
AppDomain ad = AppDomain.CreateDomain("AsmMng");
ProxyObject obj = (ProxyObject)ad. // 这里用什么方法比较合适呢??
// 这里是动态代码编译所得到的结果, 现在已经得到了一个Assembly, 而不是需要从一个文件进行加载.
#11
我这样也试过,仍然报错:
InnerException: 未能加载文件或程序集“ve0edgvc, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
Message: 未能加载文件或程序集“System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
...
CompilerResults cr = ClsCodeCompiler.ComPile(sCode, false); // 动态编译代码,
Assembly asm = cr.CompiledAssembly;
AppDomain ad = AppDomain.CreateDomain("AsmMng");
AssemblyName asmName = asm.GetName();
asm = ad.Load(aa); // 这里就报错
InnerException: 未能加载文件或程序集“ve0edgvc, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
Message: 未能加载文件或程序集“System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
#12
不懂,学习了
#13
不懂,帮顶下
#14
关注,期待解决方案。
#15
高手帮我想想办法吧....不然明天周未又没啦.....
#16
BackgroundWorker还保留着么?
停掉不就可以了?
直接执行CancelAsync()?
停掉不就可以了?
直接执行CancelAsync()?
#17
你这里貌似有点胡乱。估计你也工作忙累了。
你要释放资源,这个要实现IDispose接口,主动的调用释放,或是等垃圾回收来释放。对非托管资源,实现析构函数来释放。
对于线程,当然想办法终止掉了。和你反射没关系。反射的资源就随他去吧。线程停止掉就行了。
可能我没理解你真正的问题。所以我觉得这是理所应当。说的不对的地方,你再描述一下你的问题。
你要释放资源,这个要实现IDispose接口,主动的调用释放,或是等垃圾回收来释放。对非托管资源,实现析构函数来释放。
对于线程,当然想办法终止掉了。和你反射没关系。反射的资源就随他去吧。线程停止掉就行了。
可能我没理解你真正的问题。所以我觉得这是理所应当。说的不对的地方,你再描述一下你的问题。
#18
mark,回家慢慢看
#19
不仅仅是线程终止 ,还有其他资源都需要释放, 仅仅实现IDispose不能解决这个问题,因为不是调用完类里面的方法后就释放, 需要让这个方法里面的线程继续工作一段时间
我看了下,要卸载Assembly确实需要在一个单独的Appdomain中加载这个Assembly,然后释放的时候,将整个Appdomain卸载..
现在的问题主要是在10楼和11楼, 怎样在另一个appdomain中,加载这个Assembly.
#20
顶,没学会
#21
你并不需要新建一个appDomain仅仅为了释放资源, 有很多方法可以用, 比如说myChangeMethod()方法调用完了后直接Dispose, 但是在dispose方法里等待线程执行完。
同步/互斥, 很容易实现的。
同步/互斥, 很容易实现的。
#22
类:
实现该接口, 并且在类中,有一个 BackgroundWorker , 在类的方法 myChangeMethod 中, 执行
在这个类中再加一个接口,IDisposable
释放这个就可以了。或者ITemplate_DataChanger直接继承IDisposable
在类的释放里写一些东东。
这样就可以了。
用这个BackgroundWorker 东东,不是明志的选择。
实现该接口, 并且在类中,有一个 BackgroundWorker , 在类的方法 myChangeMethod 中, 执行
在这个类中再加一个接口,IDisposable
释放这个就可以了。或者ITemplate_DataChanger直接继承IDisposable
在类的释放里写一些东东。
这样就可以了。
用这个BackgroundWorker 东东,不是明志的选择。
#23
从未考虑过如何释放 反射后的 资源,来学习下!
#24
using System;
using System.Collections.Generic;
using System.Text;
using System.Data ;
namespace Person
{
public interface IPerson:IDisposable
{
DataTable fnGetAllFriends();
string p_Name { get; set; }
int p_Age { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
namespace Person
{
public class PersonZhang:IPerson
{
string _name = string.Empty;
int _age = 0;
DataTable _friends = null;
#region IPerson 成员
public System.Data.DataTable fnGetAllFriends()
{
return this._friends;
}
public string p_Name
{
get
{
return this._name;
}
set
{
this._name = value;
}
}
public int p_Age
{
get
{
return this._age;
}
set
{
this._age = value;
}
}
#endregion
#region IDisposable 成员
public void Dispose()
{
this._friends.Dispose();
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string path = string.Empty;
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "*.dll|*.dll";
if (dlg.ShowDialog() == DialogResult.OK)
{
path = dlg.FileName;
Assembly ass = Assembly.LoadFile(path);
object obj = ass.CreateInstance(typeof(Person.PersonZhang).FullName, true);
Person.IPerson ip = obj as Person.IPerson;
if (ip != null)
{
ip.Dispose();
}
}
}
}
}
#25
也是第一次写这个东东。不知道对不对。
#26
确实,这是其中一种方法 , 但 ip.Dispose(); 这一句, 只是释放掉对象里面的一个变量而已,并不能使整个obj对象释放....
#27
创建:
var domain = AppDomain.CreateDomain("xxx");
var asm = domain.Load("assembly");
var object = asm.CreateInstance("type");
销毁:
AppDomain.Unload(domain);
Unload完全成功还有个前提条件,创建的object的类型必须继承自MarshalByRefObject,比如:
class objecttype : MarshalByRefObject, Ixxxx
{
}
var domain = AppDomain.CreateDomain("xxx");
var asm = domain.Load("assembly");
var object = asm.CreateInstance("type");
销毁:
AppDomain.Unload(domain);
Unload完全成功还有个前提条件,创建的object的类型必须继承自MarshalByRefObject,比如:
class objecttype : MarshalByRefObject, Ixxxx
{
}
#28
哥, 网上都这么写的,可是能用在实际项目中吗??
我现在的代码:
foreach (AssemblyName asmName in cr.CompiledAssembly.GetReferencedAssemblies())
{
Assembly ass = _ad.Load(asmName);
}
Assembly ass1 = _ad.Load(cr.CompiledAssembly.GetName()); // 这一句可能有问题,因为返回值是 null
object[] objPara = ....;// 这里是获取构造函数的参数
object ooo = _ad.CreateInstance(cr.CompiledAssembly.FullName, _ad.FriendlyName + "." + sClassName, true, BindingFlags.Default, null, objPara, null, null, null); // 这里就直接报错, 没找到程序集
#29
动态编译的时候编译选项GenerateInMemory=false,OutputAssembly=文件名,生成临时assembly文件不要直接创建在当前domain里,或者索性在新的domain进行动态编译。
#30
objCompilerParameters.GenerateExecutable = false;
objCompilerParameters.GenerateInMemory = true;
objCompilerParameters.OutputAssembly = "abc";
项目规定了,只能输出到内存, 所以 GenerateInMemory=true
索性在新的domain进行动态编译?这样更复杂了.. 而且我还得在主appDomain中调用 ....
#31
交给.Net的垃圾回收机制
释放Assembly的资源AppDomain.Unload 方法
释放Assembly的资源AppDomain.Unload 方法
#32
学习了!~~~~
#33
哥...你这种回帖是毫无意义的....
我现在就想知道,为什么从文件加载就可以,从Assembly对象就不行呢?
#34
UPUP...
#1
学习下!不明白
#2
交给.Net的垃圾回收机制
释放Assembly的资源AppDomain.Unload 方法
释放Assembly的资源AppDomain.Unload 方法
#3
1.如果你想保持你一直都只有一个实例对象的话,那么你可以使用单键(或者叫单例)模式来实现,比如:
C#实现Singleton的两种方法的比较
2.如果不是第1种情况,你想知道是否放掉了你实例,那么你的可以实现实现IDisposable接口.
析构函数、finalize、dispose、close的区别以及using()的用
C#实现Singleton的两种方法的比较
2.如果不是第1种情况,你想知道是否放掉了你实例,那么你的可以实现实现IDisposable接口.
析构函数、finalize、dispose、close的区别以及using()的用
#4
可是我是在当前域中,创建的Assembly.....请问能再讲细一吗??
应该怎样使用 AppDomain.Unload 呢?? 谢谢
#5
支持 实现实现IDisposable接口
#6
请问一下, 通过反射创建的实例, 这种方法好使吗??
#7
除了你将当前域给卸载了,这点MSDN中说的很清楚,反射加载的不能单载卸载某个类
如果你要能卸载程序集的话,单独创建一个域,用完后卸载域就行了
#8
#9
#10
亲爱的美羊羊童鞋,以及如梦哥和其他高手:
我现在重新创建一个程序域, 用于管理这些程序集
我现在重新创建一个程序域, 用于管理这些程序集
AppDomain ad = AppDomain.CreateDomain("AsmMng");
ProxyObject obj = (ProxyObject)ad. // 这里用什么方法比较合适呢??
// 这里是动态代码编译所得到的结果, 现在已经得到了一个Assembly, 而不是需要从一个文件进行加载.
#11
我这样也试过,仍然报错:
InnerException: 未能加载文件或程序集“ve0edgvc, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
Message: 未能加载文件或程序集“System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
...
CompilerResults cr = ClsCodeCompiler.ComPile(sCode, false); // 动态编译代码,
Assembly asm = cr.CompiledAssembly;
AppDomain ad = AppDomain.CreateDomain("AsmMng");
AssemblyName asmName = asm.GetName();
asm = ad.Load(aa); // 这里就报错
InnerException: 未能加载文件或程序集“ve0edgvc, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
Message: 未能加载文件或程序集“System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
#12
不懂,学习了
#13
不懂,帮顶下
#14
关注,期待解决方案。
#15
高手帮我想想办法吧....不然明天周未又没啦.....
#16
BackgroundWorker还保留着么?
停掉不就可以了?
直接执行CancelAsync()?
停掉不就可以了?
直接执行CancelAsync()?
#17
你这里貌似有点胡乱。估计你也工作忙累了。
你要释放资源,这个要实现IDispose接口,主动的调用释放,或是等垃圾回收来释放。对非托管资源,实现析构函数来释放。
对于线程,当然想办法终止掉了。和你反射没关系。反射的资源就随他去吧。线程停止掉就行了。
可能我没理解你真正的问题。所以我觉得这是理所应当。说的不对的地方,你再描述一下你的问题。
你要释放资源,这个要实现IDispose接口,主动的调用释放,或是等垃圾回收来释放。对非托管资源,实现析构函数来释放。
对于线程,当然想办法终止掉了。和你反射没关系。反射的资源就随他去吧。线程停止掉就行了。
可能我没理解你真正的问题。所以我觉得这是理所应当。说的不对的地方,你再描述一下你的问题。
#18
mark,回家慢慢看
#19
不仅仅是线程终止 ,还有其他资源都需要释放, 仅仅实现IDispose不能解决这个问题,因为不是调用完类里面的方法后就释放, 需要让这个方法里面的线程继续工作一段时间
我看了下,要卸载Assembly确实需要在一个单独的Appdomain中加载这个Assembly,然后释放的时候,将整个Appdomain卸载..
现在的问题主要是在10楼和11楼, 怎样在另一个appdomain中,加载这个Assembly.
#20
顶,没学会
#21
你并不需要新建一个appDomain仅仅为了释放资源, 有很多方法可以用, 比如说myChangeMethod()方法调用完了后直接Dispose, 但是在dispose方法里等待线程执行完。
同步/互斥, 很容易实现的。
同步/互斥, 很容易实现的。
#22
类:
实现该接口, 并且在类中,有一个 BackgroundWorker , 在类的方法 myChangeMethod 中, 执行
在这个类中再加一个接口,IDisposable
释放这个就可以了。或者ITemplate_DataChanger直接继承IDisposable
在类的释放里写一些东东。
这样就可以了。
用这个BackgroundWorker 东东,不是明志的选择。
实现该接口, 并且在类中,有一个 BackgroundWorker , 在类的方法 myChangeMethod 中, 执行
在这个类中再加一个接口,IDisposable
释放这个就可以了。或者ITemplate_DataChanger直接继承IDisposable
在类的释放里写一些东东。
这样就可以了。
用这个BackgroundWorker 东东,不是明志的选择。
#23
从未考虑过如何释放 反射后的 资源,来学习下!
#24
using System;
using System.Collections.Generic;
using System.Text;
using System.Data ;
namespace Person
{
public interface IPerson:IDisposable
{
DataTable fnGetAllFriends();
string p_Name { get; set; }
int p_Age { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
namespace Person
{
public class PersonZhang:IPerson
{
string _name = string.Empty;
int _age = 0;
DataTable _friends = null;
#region IPerson 成员
public System.Data.DataTable fnGetAllFriends()
{
return this._friends;
}
public string p_Name
{
get
{
return this._name;
}
set
{
this._name = value;
}
}
public int p_Age
{
get
{
return this._age;
}
set
{
this._age = value;
}
}
#endregion
#region IDisposable 成员
public void Dispose()
{
this._friends.Dispose();
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string path = string.Empty;
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "*.dll|*.dll";
if (dlg.ShowDialog() == DialogResult.OK)
{
path = dlg.FileName;
Assembly ass = Assembly.LoadFile(path);
object obj = ass.CreateInstance(typeof(Person.PersonZhang).FullName, true);
Person.IPerson ip = obj as Person.IPerson;
if (ip != null)
{
ip.Dispose();
}
}
}
}
}
#25
也是第一次写这个东东。不知道对不对。
#26
确实,这是其中一种方法 , 但 ip.Dispose(); 这一句, 只是释放掉对象里面的一个变量而已,并不能使整个obj对象释放....
#27
创建:
var domain = AppDomain.CreateDomain("xxx");
var asm = domain.Load("assembly");
var object = asm.CreateInstance("type");
销毁:
AppDomain.Unload(domain);
Unload完全成功还有个前提条件,创建的object的类型必须继承自MarshalByRefObject,比如:
class objecttype : MarshalByRefObject, Ixxxx
{
}
var domain = AppDomain.CreateDomain("xxx");
var asm = domain.Load("assembly");
var object = asm.CreateInstance("type");
销毁:
AppDomain.Unload(domain);
Unload完全成功还有个前提条件,创建的object的类型必须继承自MarshalByRefObject,比如:
class objecttype : MarshalByRefObject, Ixxxx
{
}
#28
哥, 网上都这么写的,可是能用在实际项目中吗??
我现在的代码:
foreach (AssemblyName asmName in cr.CompiledAssembly.GetReferencedAssemblies())
{
Assembly ass = _ad.Load(asmName);
}
Assembly ass1 = _ad.Load(cr.CompiledAssembly.GetName()); // 这一句可能有问题,因为返回值是 null
object[] objPara = ....;// 这里是获取构造函数的参数
object ooo = _ad.CreateInstance(cr.CompiledAssembly.FullName, _ad.FriendlyName + "." + sClassName, true, BindingFlags.Default, null, objPara, null, null, null); // 这里就直接报错, 没找到程序集
#29
动态编译的时候编译选项GenerateInMemory=false,OutputAssembly=文件名,生成临时assembly文件不要直接创建在当前domain里,或者索性在新的domain进行动态编译。
#30
objCompilerParameters.GenerateExecutable = false;
objCompilerParameters.GenerateInMemory = true;
objCompilerParameters.OutputAssembly = "abc";
项目规定了,只能输出到内存, 所以 GenerateInMemory=true
索性在新的domain进行动态编译?这样更复杂了.. 而且我还得在主appDomain中调用 ....
#31
交给.Net的垃圾回收机制
释放Assembly的资源AppDomain.Unload 方法
释放Assembly的资源AppDomain.Unload 方法
#32
学习了!~~~~
#33
哥...你这种回帖是毫无意义的....
我现在就想知道,为什么从文件加载就可以,从Assembly对象就不行呢?
#34
UPUP...