Подтвердить что ты не робот

Безопасны ли потоки статических методов

У меня есть статический класс таймера, который будет вызываться ЛЮБОЙ веб-страницей, чтобы рассчитать, как долго каждая страница должна быть построена.

Мой вопрос: безопасны ли статические классы? В моем примере одновременные пользователи вызывают проблемы с моим временем начала и остановки? например, разные потоки, переписывающие значения начала и остановки.

public static class Timer
{
    private static DateTime _startTime;
    private static DateTime _stopTime;    

    /// <summary>
    /// Gets the amount of time taken in milliseconds
    /// </summary>
    /// <returns></returns>
    public static decimal Duration()
    {
        TimeSpan duration =  _stopTime - _startTime;
        return duration.Milliseconds;
    }

    public static void Start()
    {
        _startTime = DateTime.Now;
    }

    public static void Stop()
    {
        _stopTime = DateTime.Now;
    }
}

Если этот класс нестационарный?

(Этот класс вызывается из главной страницы asp.net.)

4b9b3361

Ответ 1

Статические методы по своей сути не являются потокобезопасными. С их помощью они не обрабатываются иначе, чем методы экземпляров. Разница в том, что обычно нужно попытаться сделать их потокобезопасными. (Я не могу думать о каких-либо статических методах .NET BCL, которые не являются потокобезопасными.) Методы экземпляров часто не являются потокобезопасными, потому что типичный шаблон заключается в создании объекта и его повторном использовании из одного потока, и если он необходимо использовать из нескольких потоков, причем координация включает в себя обеспечение безопасного использования объекта. В очень многих случаях это более целесообразно делать в координирующем коде, чем в самом объекте. (Обычно вы хотите, чтобы целые последовательности операций были эффективно атомарными - что-то, что невозможно сделать в объекте.)

Ваш класс Timer наиболее определенно не является потокобезопасным: два потока могут легко срывать друг с другом данные, и нет ничего, чтобы остановить поток от использования "устаревших" данных при расчете продолжительности.

Вместо этого используйте Stopwatch - для чего он нужен. По общему признанию, если вы хотите использовать один экземпляр из нескольких потоков, вам нужно предпринять обычные шаги для обеспечения безопасности, но вы будете в гораздо лучшем положении в целом. По общему признанию, Stopwatch далек от совершенства - см. этот вопрос и комментарий ниже для более подробной информации - но это, по крайней мере, то, для чего предназначен тип. (Кто знает, это может быть исправлено некоторое время...)

Ответ 2

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

Подводя итог, во-первых, ваши статические переменные будут совместно использоваться. Если вы можете сделать их локальными переменными, даже если они являются локальными для статического метода, они все равно получат свой собственный стек стека и, таким образом, будут потокобезопасными. Кроме того, если вы в противном случае защитите свои статические переменные (т.е. Блокировки и/или другие многопоточные методы программирования, упомянутые другими в этом потоке), вы также можете сделать ваш образец статического класса потокобезопасным.

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

Ответ 3

Ваш класс таймера определенно не является потокобезопасным. Вы должны создать нормальный класс и создавать его каждый раз, когда вам нужно измерить время:

Timer timer = new Timer();

timer.Start();
//...
timer.Stop();

decimal duration = timer.Duration();

Еще лучше, есть встроенный класс .NET, который делает именно это:

Stopwatch sw = Stopwatch.StartNew();

sw.Stop();

TimeSpan duration = sw.Elapsed;

Ответ 4

Да, вы правы, статические члены/аксессоры в этом классе заставят их перезаписываться разными пользователями.

Вот почему у вас есть экземпляры и нестатические элементы.