主线程里有个自定义类对象集合List<UserObj> list,UserObj是自定义类有n个子线程,子线程负责从不同的网络端口接收数据并存到主线程的数据集合里:
UserObj obj1=new UserObj();
list.Add(obj1);子线程负责往list里添加新的数据,主线程负责把list里现有的数据存数据库然后删除list里已保存的数据问题是主线程里list.remove(obj)之后,obj这个用户自定义类对象还存在,怎样销毁它?
我现在的程序从任务管理器里看内存使用在不断增长在说明一下我的纠结:obj是在子线程被创建的,之后添加到主线程的list中,list用完之后虽然remove了但这个对象还在,我要销毁它,要不然内存使用会不断增长以致程序over(现在确实如此),我要销毁obj,在哪销毁,怎样销毁谢谢!

解决方案 »

  1.   

    using(UserObj obj=new UserObj())
    {
    .....代码处理
    }
    把对象放using里,出了代码块对象自动销毁
      

  2.   

    UserObj 实现 IDisposable 接口不知道行不行对于这个问题好像没什么好方法....
      

  3.   

    线程运行完之后将自动终止,然后会由CLR来决定什么时候销毁来释放内存和其他资源,一般的说,当你的资源不够或有更高优先级的要求时,内存会被释放,以避免影响CPU性能。如果你实在不放心,用abort终止掉它吧!
    th.Abort();
      

  4.   

    问题是主线程里list.remove(obj)之后,obj这个用户自定义类对象还存在,怎样销毁它?
    我现在的程序从任务管理器里看内存使用在不断增长在说明一下我的纠结:obj是在子线程被创建的,之后添加到主线程的list中,list用完之后虽然remove了但这个对象还在,我要销毁它,要不然内存使用会不断增长以致程序over(现在确实如此),我要销毁obj,在哪销毁,怎样销毁
    ------------------------------------------------------------remove之后,会按照垃圾回收的原则,检查,没有引用指向这块内存,最终执行析构函数,至于什么时候执行就不一定了。如果你的对象使用了非托管资源,又实现了IDispose接口,你需要手工的调用Dispose或是在析构函数中调用Dispose释放非托管资源,比如:文件操作的句柄,Bitmap对象,设备句柄,GDI/GDI+句柄等。你没说明的部分可能隐藏了问题。你确定一下我上面说的问题先,有没有使用什么消耗内存多的东西,有没有写Dispose,有没有调用Dispose。
      

  5.   

    回复wuyazhe:首先,我可以确定是因为没有释放自定义类对象或没有释放list已移除的成员对象导致我的程序内存使用增长的,因为在没加这段代码之前,我的程序好好的。其次,我的自定义类没有实现IDispose接口,我以前写自定义类也从未实现过该接口你的回答对我有用,谢谢,我现在纠结:是不是list执行remove后,是不是还用引用指向这个对象还用如果实现IDispose接口,那dispose方法里写什么呢?this.dispose()??还是什么也不用写
      

  6.   

    其实你只要不频繁的调用,在必要时候,手工执行 GC.Collect还是有必要的。
      

  7.   

    理论上是不会出现这种情况的,来点代码吧。
    BTW,LZ这样两个线程管理一个List,容易出问题,另外用List删除效率比较低。
      

  8.   

    //自定义类    public class StateDataObj
        {
            private List<byte> stateByte;
            public List<byte> StateByte
            {
                get { return stateByte; }
                set { stateByte = value; }
            }
            private int craneID;
            public int CraneID
            {
                get { return craneID; }
                set { craneID = value; }
            }        public StateDataObj(List<byte> _stateByte, int _craneID)
            {
                stateByte = _stateByte;
                craneID = _craneID;
            }
        }
    //主线程里
            
            private List<StateDataObj> stateDatas;
            public MainForm()
            {
                InitializeComponent();
                stateDatas = new List<StateDataObj>(); 
                timer1.Start();
            }
            private void timer1_Tick(object sender, EventArgs e)
            {
                while (stateDatas.Count > 0)
                {
                    StateDataObj obj = stateDatas[0];
                    DataEngine.AddState(obj.StateByte, obj.CraneID); //存数据库
                    stateDatas.Remove(obj);
                }   
            } //子线程里
    stateDatas.Add(new StateDataObj(buf, portNum));
      

  9.   

    我是想那list当数据缓冲使,不知道用没有更好的方法,高手指点
      

  10.   

    LZ可以先通过建立弱引用,看看StateDataObj对象是否真的被GC回收了。从代码来看,最好用Queue,别用List。另外            while (stateDatas.Count > 0)
                {
                    StateDataObj obj = stateDatas[0];
                    DataEngine.AddState(obj.StateByte, obj.CraneID); //存数据库
                    stateDatas.Remove(obj);
                }  
    这段代码逻辑上没问题,但比较邪恶,Remove太频繁了,多线程时容易出问题。最好能把写操作Invoke给一个线程。
      

  11.   


                while (stateDatas.Count > 0)
                {
                    StateDataObj obj = stateDatas[0];
                    DataEngine.AddState(obj.StateByte, obj.CraneID); //存数据库
                    stateDatas.Remove(obj);
                }  
    至少可以优化为
                int count = 0;
                while (stateDatas.Count > count)
                {
                    StateDataObj obj = stateDatas[0];
                    DataEngine.AddState(obj.StateByte, obj.CraneID); //存数据库
                    count++;
                    
                }              stateDatas.Clear();
      

  12.   

    搞错了,改一下            int count = 0;
                while (stateDatas.Count > count)
                {
                    StateDataObj obj = stateDatas[count];
                    DataEngine.AddState(obj.StateByte, obj.CraneID); //存数据库
                    count++;
                    
                }              stateDatas.Clear();
      

  13.   

    C#中好像有这个问题。假如一个List<string>在方法中使用完毕后,如果不提示系统GC,系统很长时间都不会去管这部分数据。
    所以用C#的容器时候,如果数据量较大,最好处理完数据之后用GC提示系统一下。对于容器中的数据增删操作较多,数据量较大的情况,我想到的解决方案是写一个Schedule,定时提醒系统Collect。不知道能不能行,GC操作很慢啊。