2012-06-13 86 views
2

我正在开发一个c#windows窗体GUI监控应用程序,它读取数据库表并发送MAIL和SMS警报。 所以为了监控数据库和发送邮件和短信,我已经使用了几秒钟后调用的c#Timer, 一旦发送并发送邮件GUI列表框将通过执行异步功能的后台工作人员进行更新。如何同步计时器事件?

在异步函数中,我获取数据库值并分离出两个线程来发送Mail和SMS。

但是,如果它需要这么长时间,计时器线程重叠并且异步函数重叠。 所以它会多次发送同一邮件。如何解决这个问题?这是由于计时器重叠而发生的吗?

t.Interval = cn.MtimeOut; 
t.Enabled = true; 
t.Tick += new System.EventHandler(OnTimerEvent); 

OnTimerEvent实施

private void OnTimerEvent(object sender, EventArgs e) 
{ 
    lock (_objLock) 
    { 
     this.startMonitor(); 
    } 
} 

private void startMonitor() 
{ 
    MyList = new List<string>(); 
    var bw = new BackgroundWorker(); 
    bw.DoWork += (o, args) => asyncMonitor(); /* function which does sending 
               mail SMS and database reading*/ 

    bw.RunWorkerCompleted += (o, args) => UpdateControl();//update list box 
    bw.RunWorkerAsync(); 
} 

private void asyncMonitor() 
{ 
    /* READ DATABASE TABLES AND DO CALCULATIONS 
     WHICH TAKES CONSIDERABLE AMOUNT OF TIME */ 

    // Thread for sending MAIL by execute MailLogEvent method 
    Thread trd = new Thread(MailLogEvent); 

    // Thread for sending SMS by execute SmsLogEvent method 
    Thread trd2 = new Thread(SmsLogEvent); 

    //parameters for above functions 
    trd2.Start(lg); 
    trd.Start(lg); 
} 

我甚至已经用锁定时器事件和短信邮件发送方法,但它并不同步。

回答

1

我有点在几个月前做过类似的事情。

创建一个共享类,维持该邮件是在队列中,请确保您使用的锁{}你在队列中保持邮件的唯一

所以如果花费太多时间和定时器GET再次用相同的一组邮件发送它会知道它存在于队列中,并且不会尝试再次发送它

0

一种方法是将“锁定”添加到数据库。通过这种方法,您可以为每个要发送的短信/邮件添加一个类似“状态”的列。当计时器检索一行并将其排队以便发送时,它会将记录的状态更新为“挂起”或类似的东西。然后,当它实际发送消息时,它会将状态更新为“完成”。随后的重叠计时器调用将知道不处理处于“挂起”状态的记录。

+0

这是我的选择之一,它的问题是,如果应用程序崩溃会发生什么?你需要将记录的状态从“待处理”重置为“未发送”,这并不难,但它添加让我们把它称为逻辑的“复杂性” – Fredou