2

データベース テーブルを読み取り、MAIL および SMS アラートを送信する ac# Windows フォーム GUI 監視アプリケーションを開発しています。したがって、データベースを監視し、メールと SMS を送信するために、数秒後に呼び出される c# タイマーを使用しました。送信とメールが送信されると、非同期関数を実行するバックグラウンド ワーカーによって GUI リスト ボックスが更新されます。

非同期関数では、データベースの値を取得し、2 つのスレッドをスピンオフしてメールと 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);
}

Timer イベントや SMS MAIL の送信メソッドにも lock を使用しましたが、同期しません。

4

2 に答える 2

1

私は数ヶ月前に似たようなことをしました。

どのメールがキューにあるかを維持する共有クラスを作成し、必ずロック { } を使用し、キュー内のメールの一意性を維持します

そのため、時間がかかりすぎて同じセットのメールでタイマーが再び起動した場合、それがキューに存在することがわかり、再度送信しようとしません

于 2012-06-13T03:33:40.900 に答える
0

これを行う 1 つの方法は、データベースに「ロック」を追加することです。このアプローチでは、発送される各 SMS/メールに「ステータス」のような列を追加します。タイマーが行を取得して送信するためにキューに入れると、レコードのステータスが「保留中」などに更新されます。次に、実際にメッセージをディスパッチすると、ステータスが「完了」に更新されます。後続のオーバーラップ タイマー呼び出しは、「保留中」状態のレコードを処理しないことを認識します。

于 2012-06-13T03:33:41.290 に答える