Должен ли я блокировать, даже когда я последовательно обрабатываю - PullRequest
0 голосов
/ 05 августа 2010

У меня есть служба Windows, которая периодически должна выполнять какую-то работу.Поэтому я настроил System.Timers.Timer для этого.Предположим, что время обработки может быть больше, чем интервал таймера.Предположим также, что это будет очень плохо, если это произойдет.

Чтобы избежать этого, я устанавливаю автосброс на таймере на 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
     }     

}

РЕДАКТИРОВАТЬ: Уточнение моего вопроса

Я придумал службу, чтобы быть однопоточным, поэтому мне не нужна блокировка,Если я добавлю блокировку, я все еще в своем бюджете производительности, поэтому производительность не является причиной для этого.

По сути, я взвешиваю две стороны и пытаюсь разобраться, что такое Right Thing ™,Со стороны «Без блокировки» я полагаюсь на хитрость в правильности моего кода.На стороне «Блокировки» я бы добавил ненужный код.

Что лучше?

Ответы [ 3 ]

2 голосов
/ 05 августа 2010

Я бы либо полностью поточил потокобезопасность, либо вообще не делал потокобезопасность и просто написал бы в своей документации очень четко, что класс не является поточно-безопасным.

Самое худшее - вернуться через пару лет и не вспоминать, все ли безопасно. Затем вы тратите много времени на изучение своего кода или, что еще хуже, вводите себя в заблуждение.

0 голосов
/ 05 августа 2010

Как и другие говорили, если это один поток, нет необходимости в блокировке. Кроме того, вы можете пропустить таймер все вместе:

        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);
        }
0 голосов
/ 05 августа 2010

Вам нужно только lock, если с объектами будет работать более одного потока.В вашем случае ваш дизайн предотвращает это когда-либо, поэтому нет необходимости блокировать.

Единственное реальное преимущество добавления блокировки, в этом случае, состоит в том, чтобы предотвратить возникновение проблем, если вы позже изменитеваш алгоритм планирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...