2

構成からタイマー読み取り間隔を持つWindowsサービスがあります。

DipRedipServiceTimer_Elapsedイベントは、サービスの最初の実行で1000ミリ秒後に呼び出されます。このメソッドで記述されたコードは、このタイマーの次のサイクルを実行する前に実行する必要があります。ただし、最初のサイクルがまだ完了していない場合でも、DipRedipServiceTimer_Elapsedイベントが発生するのを確認しました。この結果は、2つのスレッドが同じコードで動作し、いくつかの非常に恐ろしい問題が発生することです。これを防ぐにはどうすればよいですか?提案してください。

partial class DIPREDIPServiceHost : ServiceBase
{
    #region Private Fields
    /// <summary>
    /// Timer for polling job pool on timely basis 
    /// </summary>
    private Timer DipRedipServiceTimer;                                   
    #endregion
    public DIPREDIPServiceHost()
    {
        InitializeComponent();
    }
    protected override void OnStart(string[] args)
    {                    
        DipRedipServiceTimer = new Timer();
        DipRedipServiceTimer.Enabled = true;            
        DipRedipServiceTimer.Interval = 1000;
        DipRedipServiceTimer.AutoReset = false; 
        DipRedipServiceTimer.Elapsed += new ElapsedEventHandler(DipRedipServiceTimer_Elapsed);                        
    }
    protected override void OnStop()
    {
        if (DipRedipServiceTimer != null)
        {
            DipRedipServiceTimer.Enabled = false;
            DipRedipServiceTimer.Stop();
            DipRedipServiceTimer = null;
        }
    }
    #region "Timer Elapsed Event"
    /// <summary>
    /// Handles the Elapsed event of the timer control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.Timers.ElapsedEventArgs"/> instance containing the event data.</param>
    void DipRedipServiceTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        //disable timers as at a given time only one thread should process dip/redip. 
        DipRedipServiceTimer.Stop();
        DipRedipServiceTimer.AutoReset = false;
        DipRedipServiceTimer.Enabled = false;
        try
        {
            IDipRedipController controller = new DipRedipController();
            try
            {
                DipRedipConfiguration config = controller.GetDipRedipConfiguration();
                // In case configuration has been retrieved, set timer defined.
                if (config != null)
                {
                    //set timer interval after reading from config file.
                    DipRedipServiceTimer.Interval = config.FileGenerationInterval * 60000;
                    controller.dipRedipConfiguration = config;
                    LoggingHelper.LogMessage(String.Format("Dip Service timer initialized at {0}", DateTime.UtcNow), Source.EDiscDIPREDIPService, LogCategory.Exception);
                    //Process Dip
                    bool dipSuccess = controller.ProcessDIP();
                    //Process Re-Dip
                    bool redipSuccess = controller.ProcessREDIP();
                    //Enable timers for next cycle
                    LoggingHelper.LogMessage(String.Format("Dip Service timer completed at {0}", DateTime.UtcNow), Source.EDiscDIPREDIPService, LogCategory.Exception);
                }
                // In case configuration is null, get the default timer defined in App.Config file.
                else
                {
                    int interval = 0;
                    int.TryParse(ConfigurationManager.AppSettings.Get("DefaultTimerValue"), out interval);
                    DipRedipServiceTimer.Interval = interval * 60000;
                    LoggingHelper.LogWarning("Configuration for Dip/Redip could not be fetched from database.", Source.FileImportService, LogCategory.Exception);
                }                    
                DipRedipServiceTimer.Enabled = true;
                DipRedipServiceTimer.Start(); 
            }
            catch (FaultException ex)
            {
                LoggingHelper.LogException("Exception Occured in DipRedipServiceTimer_Elapsed method of Dip/Redip Window Service", ex, Source.EDiscDIPREDIPService);                    
            }
        }
        catch (Exception ex)
        {
            LoggingHelper.LogException("Exception Occured in the DipRedip Service Host Window Service", ex, Source.EDiscDIPREDIPService);               
        }
     }
    #endregion                 
}
4

1 に答える 1

1

次のリンク http://msdn.microsoft.com/en-us/library/system.timers.timer.interval.aspx

間隔を再設定する動作について説明します。処理を行う前にconfigから間隔を設定していたため、ドキュメントに従ってタイマーがリセットされ、elaspsedイベントが発生しました。

修正:-処理が完了した後に間隔を設定しています。これによりタイマーがリセットされ、設定された間隔の後に経過イベントが発生します。また、次のコード行はもう必要ありません

    DipRedipServiceTimer.Stop();
    DipRedipServiceTimer.AutoReset = false;
    DipRedipServiceTimer.Enabled = false;

タイマーの初期化中に自動リセットがfalseに設定されているためです。

#region "Timer Elapsed Event"
    /// <summary>
    /// Handles the Elapsed event of the timer control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.Timers.ElapsedEventArgs"/> instance containing the event data.</param>
    void DipRedipServiceTimer_Elapsed(object sender, ElapsedEventArgs e)
    {

        try
        {                
            IDipRedipController controller = new DipRedipController();
            try
            {
                DipRedipConfiguration config = controller.GetDipRedipConfiguration();                    
                if (config != null)
                {
                    //set timer interval after reading from config file.                        
                    controller.dipRedipConfiguration = config;
                    LoggingHelper.LogMessage(String.Format("Dip Service timer initialized at {0}", DateTime.UtcNow), Source.EDiscDIPREDIPService, LogCategory.Exception);
                    //Process Dip
                    bool dipSuccess = controller.ProcessDIP();
                    //Process Re-Dip
                    bool redipSuccess = controller.ProcessREDIP();
                    // In case configuration has been retrieved, set timer defined.
                    DipRedipServiceTimer.Interval = config.FileGenerationInterval * 60000;
                    //Enable timers for next cycle
                    LoggingHelper.LogMessage(String.Format("Dip Service timer completed at {0}", DateTime.UtcNow), Source.EDiscDIPREDIPService, LogCategory.Exception);
                }
                // In case configuration is null, get the default timer defined in App.Config file.
                else
                {
                    int interval = 0;
                    int.TryParse(ConfigurationManager.AppSettings.Get("DefaultTimerValue"), out interval);
                    DipRedipServiceTimer.Interval = interval * 60000;
                    LoggingHelper.LogWarning("Configuration for Dip/Redip could not be fetched from database.", Source.EDiscDIPREDIPService, LogCategory.Exception);
                }                                        
                DipRedipServiceTimer.Start();
            }
            catch (Exception ex)
            {
                LoggingHelper.LogException("Exception Occured in DipRedipServiceTimer_Elapsed method of Dip/Redip Window Service", ex, Source.EDiscDIPREDIPService);                    
            }
        }
        catch (Exception ex)
        {
            LoggingHelper.LogException("Exception Occured in the DipRedip Service Host Window Service", ex, Source.EDiscDIPREDIPService);               
        }
     }
    #endregion 
于 2012-06-19T12:19:27.773 に答える