我有10個線程,每個線程都創建了我的對象的一個新實例。調用這個對象的2個方法和線程的循環壽命結束,問題是它保留在內存中。C#COM對象不會離開內存
隨着那一小時最終發生一個內存不足。
我有以下代碼:
new Thread(Thread_).Start();
Thread.Sleep(1000);
new Thread(Thread_).Start();
Thread.Sleep(1000);
new Thread(Thread_).Start();
Thread.Sleep(1000);
new Thread(Thread_).Start();
Thread.Sleep(1000);
new Thread(Thread_).Start();
Thread.Sleep(1000);
new Thread(Thread_).Start();
Thread.Sleep(1000);
new Thread(Thread_).Start();
Thread.Sleep(1000);
new Thread(Thread_).Start();
Thread.Sleep(1000);
new Thread(Thread_).Start();
Thread.Sleep(1000);
new Thread(Thread_).Start();
Thread.Sleep(1000);
void Thread_()
{
spdNFeX _spdNFeX = new spdNFeX();
try
{
String[] Chave = (String[])Chaves.ToArray(typeof(string));
_spdNFeX.LoadConfig("");
Random Rand = new Random();
_spdNFeX.DiretorioLog = "C:\\Users\\Joao\\Documents\\Visual Studio 2012\\Projects\\TesteNFe\\TesteNFe\\bin\\Debug\\" + Convert.ToString(Rand.Next(1, 999) + "\\");
for (int i = 0; i < Chave.Length; i++)
{
_spdNFeX.ConsultarNF(Chave[i]);
Thread.Sleep(5000);
}
}
finally {
_spdNFeX = null;
}
}
我進行了以下試驗,但沒有成功。
試驗1
finally {
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(_spdNFeX);
GC.Collect();
GC.WaitForPendingFinalizers();
}
試驗2
finally {
System.Runtime.InteropServices.Marshal.ReleaseComObject(_spdNFeX);
_spdNFeX = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
試驗3
public class ComDisposer : IDisposable
{
private List<Object> _comObjs;
public ComDisposer()
{
_comObjs = new List<Object>();
}
~ComDisposer()
{
Dispose(false);
}
public T Add<T>(T o)
{
if (o != null && o.GetType().IsCOMObject)
_comObjs.Add(o);
return o;
}
public void Clear()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
for (int i = _comObjs.Count - 1; i >= 0; --i)
Marshal.FinalReleaseComObject(_comObjs[i]);
_comObjs.Clear();
}
}
void IDisposable.Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
void Thread_()
{
using (ComDisposer cd = new ComDisposer())
{
spdNFeX _spdNFeX = cd.Add(new spdNFeX());
try
{
String[] Chave = (String[])Chaves.ToArray(typeof(string));
_spdNFeX.LoadConfig("");
Random Rand = cd.Add(new Random());
_spdNFeX.DiretorioLog = "C:\\Users\\Joao\\Documents\\Visual Studio 2012\\Projects\\TesteNFe\\TesteNFe\\bin\\Debug\\" + Convert.ToString(Rand.Next(1, 999) + "\\");
for (int i = 0; i < Chave.Length; i++)
{
_spdNFeX.ConsultarNF(Chave[i]);
Thread.Sleep(5000);
}
}
finally
{
}
}
}
無論spdNFeX是什麼,我會嘗試調用'Dispose',然後將它置空,如果它是一個COM對象。 – BradleyDotNET 2014-09-03 18:33:03
我怎麼能這樣做?以前曾嘗試使用這個IDisposable接口,但沒有成功。 – 2014-09-03 18:39:54
你不能,COM對象不是一次性的。忽略該評論。使用內存分析器收集事實。並考慮死鎖的終結器線程的可能性。 – 2014-09-03 18:40:42