给System.Timer类的Elapsed事件加锁

背景:
最近在做一个项目,程序是命令行程序,在主程序中开一个线程,这个线程用到了System.Timer类的Elapsed事件,根据指定时间间隔循环去查询数据库,找符合条件的记录,把记录组织成xml对象发送到MSMQ中去。刚一开始的时候数据量小,在时间间隔内可以查询所有的记录并发送到MSMQ,随着业务量大增大,在时间间隔内会多次执行查询数据库发送MSMQ,这样就会产生重复的数据发送到MSMQ了。所以本次在System.Timer类的Elapsed事件中加锁,使上次任务执行完之前,后面的任务无法执行。

程序代码:

    public class ThreadSendMQ
    {
        public void Work(object th)
        {
            string str = "消息队列发送模式:多线程发送模式。";
            Console.WriteLine(str);

            System.Timers.Timer t = new System.Timers.Timer();
            t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);
            t.Interval = 1000 * Convert.ToInt16(ConfigManager.SleepTime);
            t.Enabled = true;
        }

        void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            //加锁检查数据库和发送MSMQ
            lock (this)
            {
                send();
            }
        }

        private void send()
        {
            string str = "线程正在发送消息队列";
            //线程查询数据库并发送到MSMQ中去。
            //Console.Write(str);
            //LogManager.WriteFilerLog(ConfigManager.LogPath, str);
        }
    }

///////   主程序  //////////////
    class Program
    {
        static void Main(string[] args)
        {
            ThreadSendMQ thSend = new ThreadSendMQ();
            System.Threading.ParameterizedThreadStart thrParm = new System.Threading.ParameterizedThreadStart(thSend.Work);
            System.Threading.Thread thread = new System.Threading.Thread(thrParm);
            thread.Start(System.Threading.Thread.CurrentThread);
        }
    }

经过上面的锁,就可以防止任务的多次执行,当前项目的bug完美解决。

时间: 2024-12-22 04:45:48

给System.Timer类的Elapsed事件加锁的相关文章

C#中timer类的用法

C#中timer类的用法 关于C#中timer类  在C#里关于定时器类就有3个   1.定义在System.Windows.Forms里   2.定义在System.Threading.Timer类里   3.定义在System.Timers.Timer类里 System.Windows.Forms.Timer是应用于WinForm中的,它是通过Windows消息机制实现的,类似于VB或Delphi中的Timer控件,内部使用API  SetTimer实现的.它的主要缺点是计时不精确,而且必须

使用System.Timers.Timer类实现程序定时执行

使用System.Timers.Timer类实现程序定时执行 在C#里关于定时器类有3个:System.Windows.Forms.Timer类.System.Threading.Timer类和System.Timers.Timer类. System.Windows.Forms.Timer是应用于WinForm中的,它是通过Windows消息机制实现的,类似于VB或Delphi中的Timer控件,内部使用API  SetTimer实现的.它的主要缺点是计时不精确,而且必须有消息循环,Consol

C#多线程 定时重复调用异步线程即System.Threading.Timer类使用小例

1.System.Threading.Timer计时器提供了一种重复调用异步线程的方法..Net BCL中有多个Timer类,如用于Windows应用程序的System.Windows.Forms.Timer类,如可以运行在用户接口线程或工作线程上的System.Timers.Timer类.它们是很不一样的,这里要讲的System.Threading.Timer类是一种定时调用某个异步线程的类.每次计时器到设定的时间,系统就去线程池中开启一个线程运行提供的回调方法. 2.调用这个Timer类的重

关于C#中timer类

·关于C#中timer类 在C#里关于定时器类就有3个 1.定义在System.Windows.Forms里 2.定义在System.Threading.Timer类里 3.定义在System.Timers.Timer类里 System.Windows.Forms.Timer是应用于WinForm中的,它是通过Windows消息机制实现的,类似于VB或Delphi中的Timer控件,内部使用API SetTimer实现的.它的主要缺点是计时不精确,而且必须有消息循环,Console Applic

C#类对象的事件定义

1. 类对象代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Timers; namespace WinformEventTest { /// <summary> /// 定义了一个 ShowString 事件的对象类 /// </summary> internal class EventClass { /// <summa

反射,System.Type类

http://m.blog.csdn.net/blog/woddle/40623333 两个现实中的例子:1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的生理情况.这是如何做到的呢?B超是B型超声波,它可以透过肚皮通过向你体内发射B型超声波,当超声波遇到内脏壁的时候就会产生一定的“回音”反射,然后把“回音”进行处理就可以显示出内脏的情况了(我不是医生也不是声学专家,不知说得是否准确^_^).2.地球内部结构:地球的内部结构大体可以分为三层:地壳.地幔和地核.地壳是固体,地

Timer类和TimerTask类

Timer类是一种线程设施,可以用来实现在某一个时间或某一段时间后安排某一个任务执行一次或定期重复执行.该功能要与TimerTask类配合使用.TimerTask类用来实现由Timer安排的一次或重复执行的某一任务. //================================================= // File Name : Timer_demo //-------------------------------------------------------------

设置定时任务(Timer类的介绍)

设置定时任务(Timer类的介绍) 在我们的许多项目中,我们都需要用到定时任务,因此想借此博文来对定时任务进行一个介绍. 设置定时任务步骤如下: 先new一个Timer对象 Timer timer = new Timer() ; 然后调用它的schedule方法,例如:timer.schedule(new Task(), 5 * 1000,5*1000); 相信上面的代码我们不会陌生,即使我们没有写过,但我们一定见到过. 要注意的是:上面第二步所提到的schedule方法有四个重载的方法.下面进

Arrays类和Timer类(定时调度)

Timer类是一种线程设施,可以用来实现在某一个时间或某一段时间后安排某一个任务执行一次或定期重复执行.该功能要与TimerTask配合使用.TimerTask类用来实现由Timer安排的一次或重复执行的某一任务. 每一个Timer对象对应的是一个线程,因此计时器所执行的任务应该迅速完成,否则可能会延迟后续任务的执行. TimerTask类是一个抽象类,如果要使用该类,需要自己建立一个类来继承此类,并实现其中的抽象方法. TimerTask的子类: // 完成具体的任务操作 import jav