C# 通过 timer.Elapsed 和单击调用方法

Posted

技术标签:

【中文标题】C# 通过 timer.Elapsed 和单击调用方法【英文标题】:C# Invoking method by timer.Elapsed and by click 【发布时间】:2016-06-18 06:41:21 【问题描述】:

我的定时器有点问题。

这是我的代码:

_uploadHelper = new DataProcessorUploadHelper((sender, args) => Start())

public void Start()

        Task.Factory.StartNew(() =>
        
            if (UploadHelper.UploadState == UploadState.UploadOn)
            
                UploadHelper.IncrementSavingRequestCounter();
            
            else
            
                UploadHelper.StopTimer();
                lock (_lock)
                
                    UploadHelper.UploadState = UploadState.UploadOn;

                    UploadData();

                    UploadHelper.UploadState = UploadState.UploadOff;
                
                UploadHelper.StartTimer();
            
        );

UploadState就是这样实现的

    private int _uploadState;

    public UploadState UploadState
    
        get  return (UploadState)_uploadState; 
        set  Interlocked.Exchange(ref _uploadState, (int)value); 
    

我正在使用 System.Timers.Timer,它应该以 10 分钟的间隔调用 Start 方法(在我的助手类中实现)。

    private Timer _intervalTimer;
    private long _savingRequestsCounter;

    public DataProcessorUploadHelper(ElapsedEventHandler callback)
    
        UploadState = UploadState.UploadOff;;
        _intervalTimer = new Timer();
        _intervalTimer.Interval = UploadIntervalTimeSpan.TotalMilliseconds;
        _intervalTimer.Elapsed += callback;
        _intervalTimer.Start();
        _intervalTimer.Enabled = true;
     
    public void StartTimer()
    
        _intervalTimer.Start();
    
    public void ResetTimer()
    
        _intervalTimer.Start();
        _intervalTimer.Stop();
    

    public void StopTimer()
    
        _intervalTimer.Stop();
    
    public void IncrementSavingRequestCounter()
    
        Interlocked.Increment(ref _savingRequestsCounter);
    

    public void DecrementSavingRequestCounter()
    
        Interlocked.Decrement(ref _savingRequestsCounter);
    

当用户点击特定按钮时也会调用此方法。

还有我的麻烦。

定时器调用 Start 方法 => UploadHelper.UploadState = UploadState.UploadOn.

而且应该被_lock锁定。

但是当用户在 UploadData() 期间点击 我看到 UploadState = UploadState.UploadOff 并且没有被锁定。

这段代码有什么问题?

为什么当定时器调用这个方法时状态不同?

【问题讨论】:

【参考方案1】:

    "...而且应该被_lock锁定"

是的,如果 _lock 在您的情况下被声明为 static

由于 Timer 的 Elapsed-Event 导致在单独的线程中调用 UploadData(),因此 _lock(如果不是静态的)每次都不是同一个 _lock 并且不用作同步对象。

    如果您的计时器来自System.Timers,那么还有另一种同步方式: 见SynchronizingObject

【讨论】:

以上是关于C# 通过 timer.Elapsed 和单击调用方法的主要内容,如果未能解决你的问题,请参考以下文章

C# System.Timers Demo

Windows服务中的Timer Elapsed事件一一

c# Timer异常停止

如何从 Timer.Elapsed 事件触发另一个事件?

在C#中Elapsed是什麽意思?

用C#写一个windows服务可定时执行sql Service数据库里面的存储过程(带两个参数),急求代码!高手赐教!