主线程里有个自定义类对象集合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,在哪销毁,怎样销毁谢谢!
UserObj obj1=new UserObj();
list.Add(obj1);子线程负责往list里添加新的数据,主线程负责把list里现有的数据存数据库然后删除list里已保存的数据问题是主线程里list.remove(obj)之后,obj这个用户自定义类对象还存在,怎样销毁它?
我现在的程序从任务管理器里看内存使用在不断增长在说明一下我的纠结:obj是在子线程被创建的,之后添加到主线程的list中,list用完之后虽然remove了但这个对象还在,我要销毁它,要不然内存使用会不断增长以致程序over(现在确实如此),我要销毁obj,在哪销毁,怎样销毁谢谢!
{
.....代码处理
}
把对象放using里,出了代码块对象自动销毁
th.Abort();
我现在的程序从任务管理器里看内存使用在不断增长在说明一下我的纠结:obj是在子线程被创建的,之后添加到主线程的list中,list用完之后虽然remove了但这个对象还在,我要销毁它,要不然内存使用会不断增长以致程序over(现在确实如此),我要销毁obj,在哪销毁,怎样销毁
------------------------------------------------------------remove之后,会按照垃圾回收的原则,检查,没有引用指向这块内存,最终执行析构函数,至于什么时候执行就不一定了。如果你的对象使用了非托管资源,又实现了IDispose接口,你需要手工的调用Dispose或是在析构函数中调用Dispose释放非托管资源,比如:文件操作的句柄,Bitmap对象,设备句柄,GDI/GDI+句柄等。你没说明的部分可能隐藏了问题。你确定一下我上面说的问题先,有没有使用什么消耗内存多的东西,有没有写Dispose,有没有调用Dispose。
BTW,LZ这样两个线程管理一个List,容易出问题,另外用List删除效率比较低。
{
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));
{
StateDataObj obj = stateDatas[0];
DataEngine.AddState(obj.StateByte, obj.CraneID); //存数据库
stateDatas.Remove(obj);
}
这段代码逻辑上没问题,但比较邪恶,Remove太频繁了,多线程时容易出问题。最好能把写操作Invoke给一个线程。
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();
while (stateDatas.Count > count)
{
StateDataObj obj = stateDatas[count];
DataEngine.AddState(obj.StateByte, obj.CraneID); //存数据库
count++;
} stateDatas.Clear();
所以用C#的容器时候,如果数据量较大,最好处理完数据之后用GC提示系统一下。对于容器中的数据增删操作较多,数据量较大的情况,我想到的解决方案是写一个Schedule,定时提醒系统Collect。不知道能不能行,GC操作很慢啊。