Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#COM对象没有离开内存_C#_Thread Safety - Fatal编程技术网

C#COM对象没有离开内存

C#COM对象没有离开内存,c#,thread-safety,C#,Thread Safety,我有10个线程,每个线程创建一个对象的新实例。调用此对象的2个方法,线程的循环寿命结束,问题是它仍保留在内存中 随着一个小时的最终发生,一个小时的记忆消失了 我有以下代码: new Thread(Thread_).Start(); Thread.Sleep(1000); new Thread(Thread_).Start(); Thread.Sleep(1000); new Thread(Thread_).Start

我有10个线程,每个线程创建一个对象的新实例。调用此对象的2个方法,线程的循环寿命结束,问题是它仍保留在内存中

随着一个小时的最终发生,一个小时的记忆消失了

我有以下代码:

        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;
    }

}
测试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
        {

        }
    }
}
公共类ComDisposer:IDisposable
{
私人名单;
公共通信处理器()
{
_comObjs=新列表();
}
~comdesser()
{
处置(虚假);
}
公共电讯管理局(电讯管理局)
{
if(o!=null&&o.GetType().iscom对象)
_添加(o);
返回o;
}
公共空间清除()
{
处置(真实);
}
受保护的虚拟void Dispose(bool disposing)
{
如果(处置)
{
对于(int i=_comObjs.Count-1;i>=0;--i)
终审法院院长;
_comObjs.Clear();
}
}
void IDisposable.Dispose()无效
{
处置(真实);
总干事(本);
}
}        
无效线程
{
使用(ComDisposer cd=新ComDisposer())
{
spdNFeX _spdNFeX=cd.Add(新的spdNFeX());
尝试
{
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(1999)+“\\”;
for(int i=0;i
使用
System.Runtime.InteropServices.Marshal.FinalReleaseComObject

无论spdNFeX是什么,我都会尝试调用它的
Dispose
,如果它是COM对象,我会先将其置零。我怎么做?以前曾尝试使用此IDisposable接口,但没有成功。您不能,COM对象不是一次性的。忽略这一评论。使用内存分析器收集事实。考虑一下僵局终结线程的可能性。请参阅如何处置COM memoryHmya,这是一个永不停止的货物崇拜。这很少是正确的答案,通常会引入更多的bug。@ScottChamberlain假设您在发布后不使用该对象,它工作正常。它只是强制引用计数为0。
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
        {

        }
    }
}