C# 多定时器的问题

临风笛 2009-09-18 10:30:16
问题如下:类中定义了一个静态的链表,该链表每隔一分钟应该更新一次(连接实时数据库根据一些信息更新值),同时在另一个每五分钟运行的函数里需要调用该链表值。于是我开启了两个定时器分别执行两个任务。
如下:
 public class Run
{
//成员变量
System.Threading.Timer PreTimer;
System.Threading.Timer convertimer;
//converdata是我定义的结构体
public static List<converdata> ldgdata = new List<converdata>();
private static int flag=0;
//构造函数
public Run()
{
PreTimer = new System.Threading.Timer(new TimerCallback(preTimer_Tick));
convertimer = new System.Threading.Timer(new TimerCallback(Convertimer_Tick));
ldgdata;//ldgdata初始化
}
//开始定时运行,启动两个定时器
public void systemRun()
{
convertimer.Change(0,60000);
PreTimer.Change(0,300000);
}

//五分钟定时预测
void preTimer_Tick(object source)
{
lock (this)
{
//这里执行其他任务,单独运行大约2分钟左右
while(true)
{
if(flag==1)
{
//这里开始调用最新更新的ldgdata链表值,大约需要半分钟左右。
}
}

}
}
//一分钟刷新链表定时器
void Convertimer_Tick(object source)
{
lock (this)
{
flag=0;
//更新链表值
flag=1;
}
}


}


现在有两个问题:1. 一分钟刷新的定时器,不是每隔一分钟都重入执行。
2. 运行一会过后,调用链表值时,发现该链表已被清空,长度为零了!难道是被GC回收了,但我是在主线程里定义的静态链表.
苦恼中,C#里的多线程和定时器一窍不通,那位大哥能指点迷津,不胜感激!
...全文
1149 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
yangjie008008 2011-10-16
  • 打赏
  • 举报
回复
大厦在
Neutroustroup 2009-09-20
  • 打赏
  • 举报
回复
不要使用lock(this),好的编程经验是:lock中的对象应该是私有的,而this是public的
Neutroustroup 2009-09-20
  • 打赏
  • 举报
回复
定时器的“回调方法”(确切的说叫委托。。。)应该是可重入的,如果在回调方法中使用同步的机制,有可能导致大量的timeelapsed的消息排队等候处理(时间间隔小的时候尤其如此,可能会出现类似“死锁”的现象发生),你5分钟的“回调”是个忙循环,问题就出现在这里

而且这个完全没必要用定时器,两个线程就可以搞定的,循环中使用wait方法,等待超时返回,进行处理就行
临风笛 2009-09-19
  • 打赏
  • 举报
回复
5楼的哥们说,开两个线程,这个怎么实现定时,用sleep吗?就是每次执行完计算下耗时T,再将线程sleep(5-T),这样行吗?请多多指点。关键是同步问题,我调用链表值时,应该保证它是最近一分钟更新的!
临风笛 2009-09-19
  • 打赏
  • 举报
回复
1楼说的在事件里暂停定时器,执行完后再重新启动,这个定时是不是不能保证了?我的这个程序需要与实时数据库连,定时精确到分钟就可以了!
临风笛 2009-09-19
  • 打赏
  • 举报
回复
我的这个程序使用winfrom开发,起始就是用了几个按钮,它是在服务器上跑的程序。
3楼说定时器lock是互斥执行的,启动一个定时器不是开个线程的?要是这样怎末实现定时功能。我的这个程序一分钟定时里面的函数执行很快的,五分钟那个定时器执行到调用值时,只要保证它是最近一分钟更新的值就行了。能给你实现的方法吗?
dfzx 2009-09-18
  • 打赏
  • 举报
回复
1.用两个线程就可以,没必要用计时器
2.静态变量不可能丢失,要吗就是被重新赋值了
much0726 2009-09-18
  • 打赏
  • 举报
回复
首先,Lock()代码是互斥执行,简单说就是两段代码不能同时执行,preTimer_Tick在运行中,Convertimer_Tick()就需要等待,因此不是每1分钟都执行的。
第二个问题,应该是线程没同步好,就象1楼说的那样,尽量使用私有对象做锁对象,关键代码没给出,不好确认在哪里清空List的,List在不改变成员时,对其访问是线程安全的,但是多线程访问时,其中有改变值的操作,就会出问题了。
redleafe 2009-09-18
  • 打赏
  • 举报
回复
学习了,不过Timer开多了,速度明显降低,很是恼人!
CopperBell 2009-09-18
  • 打赏
  • 举报
回复
up
wjq 2009-09-18
  • 打赏
  • 举报
回复
System.Threading.Timer的实现是多线程操作。如果不是Windows服务,而是winform程序,考虑使用System.Windows.Forms.Timer

另外,代码中,建议在计时器事件开始,暂停计时器,执行结束后重新开启,防止操作比较耗时,而又执行1次或数次计时器时间,造成类似死锁的恶性循环。

还有,lock()可以参考一下msdn,是不建议用lock(this)的,同时,计时器的计时并不是非常精确的。

ldgdata 被清空,我怀疑你有其他操作。

PS,List<>不是链表吧~?

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧