我用timer_tick时间 每30分钟 去执行,取设备里的信息,昨天晚上9点开启后,今天早上来程序还在运行,可是取一个设备信息
由刚开始的5秒变成了2分钟。
是何原因?public class 线程操作类
{
public object 设备信息;
public void 读取数据方法()
{
//读取并写入数据库
}
}timer_Tick(object sender, EventArgs e)
{
BackgroundWorker[] bgws = new BackgroundWorker[设备总数];
线程操作类[] temps = new 线程操作类[设备总数]; for(int i=0;i<设备总数,i++){
//实例化线程和线程操作类
bgws[i] = new BackgroundWorker();
temps[i] = new 线程操作类();
//设置线程工作的方法
bgws[i].DoWork += new DoWorkEventHandler(temps[i].读取数据方法);
//启用线程
bgws[i].RunWorkerAsync()
}
}
由刚开始的5秒变成了2分钟。
是何原因?public class 线程操作类
{
public object 设备信息;
public void 读取数据方法()
{
//读取并写入数据库
}
}timer_Tick(object sender, EventArgs e)
{
BackgroundWorker[] bgws = new BackgroundWorker[设备总数];
线程操作类[] temps = new 线程操作类[设备总数]; for(int i=0;i<设备总数,i++){
//实例化线程和线程操作类
bgws[i] = new BackgroundWorker();
temps[i] = new 线程操作类();
//设置线程工作的方法
bgws[i].DoWork += new DoWorkEventHandler(temps[i].读取数据方法);
//启用线程
bgws[i].RunWorkerAsync()
}
}
解决方案 »
- SqlDataAdapter.FillSchema方法执行存储过程返回的DataSet,有问题!
- WinForm-->DataGridView-->CheckedListBox
- 查询表中的字段值=“1”的字段SQL语句要怎么写?
- static 方法能否被 override
- datagrid中的模板列是做什么用的,哪位能给举个例子
- 求教无驱动操作DBF数据库
- 这种功能怎么实现呢?急等!!!希望各位大哥给予指导!!!
- 未将对象引用设置到对象的实例?
- 怎么把一个对象定义为全局变量!
- 急﹗急﹗如何實現CSDN樹形界面
- 未将对象引用设置到对象的实例
- Application Reference 是什么东东,他属于b/s,c/s,还是什么?
1. 内存占用过多了,造成机器很慢。其实不用每次new BackgroundWorker[设备总数];new 线程操作类[设备总数];new BackgroundWorker();new 线程操作类();new DoWorkEventHandler(temps[i].读取数据方法);这些都属于每个BackgroundWorker的配置,只需执行一次即可,然后把他存起来,定期的执行就好了。
另外,我有一个疑问,这么多设备是怎么区分的?我看new 线程操作类的时候没有对设备信息进行属性填充。
2.设备连接变慢了,数据库的连接变慢了。
不须要bgws[i].DoWork -= new DoWorkEventHandler(temps[i].读取数据方法);吗?
但是也正是因为如此,可能占用的内存就会一点一点的增多。建议修改是:public class 线程操作类
{
public object 设备信息;
public void 读取数据方法()
{
//读取并写入数据库
}
}
public BackgroundWork[] GenerateBackgroundWorks(int deviceNumber)
{
BackgroundWorker[] bgws = new BackgroundWorker[deviceNumber];
线程操作类[] temps = new 线程操作类[deviceNumber];
for(int i=0 ; i < deviceNumber ; i++)
{
//实例化线程和线程操作类
bgws[i] = new BackgroundWorker();
temps[i] = new 线程操作类();
//设置线程工作的方法
bgws[i].DoWork += new DoWorkEventHandler(temps[i].读取数据方法);
}
}//在timer_Tick执行外部定义并生成BackgroundWork
BackgroundWorker[] bgws = GenerateGenerateBackgroundWorks(设备总数);
timer_Tick(object sender, EventArgs e)
{
for(int i=0;i<设备总数,i++)
{
bgws[i].RunWorkerAsync()
}
}
可以定时执行一次强制GC,虽然你强制了,但是系统回收不回收还是系统的事情。
像是长时间执行的这种程序,如果需要精确的定时,一是将程序放进系统的Services,二是使用现有的比较好的Schedule框架,三是自己实现一套时间校对Service。不然容易出小问题。
2. 运行过程中有很多的new操作, 会占用临时空间, 而运行环境会认为这些资源可能还有用,就没有自动释放。另: To lz:
如果时间间隔过短的话,会造成BackgroundWorker处于Busy的状态,应该在实现的时候确保程序的健壮性。
程序要长时间工作的话,必须编译为Release版本,Release版本将对代码进行优化,大大提高了自动释放内存的速度,当某个对象离开了作用域将立刻释放其内存。
这里不应该使用BackgroundWorker,既然用了定时器,又需要异步执行,则应该直接使用System.Timers.Timer这个类,它非常适合你现在的应用,关于这个类的介绍,自己查看MSDN,我这里只是简单说下怎么使用。 System.Timers.Timer timer = new System.Timers.Timer(5000);
for (int i = 0; i < 设备总数; i++)
{
int j = i;//必须再给一个 变量,否则后面的委托将用i的最后一个值
timer.Elapsed += delegate
{
//这里写对应设备的处理方法
temps[j].读取数据方法
};
}
timer.Start();