代码之家  ›  专栏  ›  技术社区  ›  Conrad Frix

即使在顺序处理时也应该阻止吗

  •  0
  • Conrad Frix  · 技术社区  · 14 年前

    为了避免这种情况,我将计时器上的AutoReset设置为false,然后在进程中调用start。

    public partial class Service : ServiceBase{
    
        System.Timers.Timer timer;
    
    
     public Service()
        {
    
        timer = new System.Timers.Timer();
        //When autoreset is True there are reentrancy problme 
        timer.AutoReset = false;
    
    
        timer.Elapsed += new System.Timers.ElapsedEventHandler(DoStuff);
    }
    
     protected override void OnStart(string[] args)
     {
    
         timer.Interval = 1;
         timer.Start();
    
        }
    
     private void DoStuff(object sender, System.Timers.ElapsedEventArgs e)
     {
    
        Collection stuff = GetData();
        LastChecked = DateTime.Now;
    
        foreach (Object item in stuff)
        {
              item.Dosomthing(); //Do somthing should only be called once
         }     
    
    
        TimeSpan ts = DateTime.Now.Subtract(LastChecked);
        TimeSpan MaxWaitTime = TimeSpan.FromMinutes(5);
    
    
        if (MaxWaitTime.Subtract(ts).CompareTo(TimeSpan.Zero) > -1)
            timer.Interval = MaxWaitTime.Subtract(ts).TotalMilliseconds;
        else
            timer.Interval = 1;
    
        timer.Start();
    
    
    
    
    
     }
    

    当前代码没有阻塞,因为我知道它正在被顺序处理,因为AutoReset=false。但我可以用另一种方式

    lock(myLock)
    {
        Collection stuff = GetData();
        LastChecked = DateTime.Now;
    
        foreach (Object item in stuff)
        {
              item.Dosomthing(); //Do somthing should only be called once
         }     
    
    }
    

    编辑: 澄清我的问题

    我把服务设计成单线程的,所以我不需要锁。如果我加了锁,我仍然在我的性能预算之内,所以性能不是不加锁的理由。

    基本上,我是在权衡两个方面,我试图找出什么是正确的。 在“无锁”方面,我依靠一种发明来确保代码的正确性。在“锁”方面,我会添加不必要的代码。

    3 回复  |  直到 14 年前
        1
  •  2
  •   Rei Miyasaka    14 年前

    我要么全力以赴保证线程安全,要么根本不保证线程安全,然后在文档中非常清楚地写下类不是线程安全的。

    最糟糕的是几年后回来却不记得一切是否安全。然后你会浪费大量的时间来研究你的代码,或者更糟的是,你会误导自己。

        2
  •  0
  •   Reed Copsey    14 年前

    你只需要 lock 如果有多个线程将处理这些对象。在您的情况下,您的设计阻止了这种情况的发生,因此不需要锁定。

    在本例中,添加锁的唯一真正好处是,如果以后更改调度算法,可以防止问题的发生。

        3
  •  0
  •   Jess    14 年前

            TimeSpan maxInterval = new TimeSpan(0, 10, 0);
            while(true)
            {
                DateTime startTime = DateTime.UtcNow;
    
    
                //Do lots and lots of work
    
    
                TimeSpan ts = DateTime.UtcNow - startTime;
                ts = (ts > maxInterval ? new TimeSpan(0) : maxInterval-ts);
                Thread.Sleep(ts);
            }