2012-06-13 141 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