我有一个静态计时器类,任何网页都会调用它来计算每个页面构建的时间.
我的问题是静态类线程安全吗?在我的示例中,并发用户会导致启动和停止时间出现问题吗?例如,不同的线程覆盖我的开始和停止值.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
这个类应该是非静态类吗?
(这个类将从asp.net主页调用.)
Jon*_*eet 66
静态方法本质上不是线程安全的.CLR与实例方法的处理方式没有区别.不同之处在于,通常应该尝试使它们具有线程安全性.(我想不出任何不是线程安全的.NET BCL静态方法.)实例方法通常不是线程安全的,因为典型的模式是创建一个对象并从一个线程重复使用它,如果它也必须从多个线程使用,统筹涉及包括确保该对象的安全使用.在很多情况下,在协调代码中比在对象本身中更合适.(通常你想让整个操作序列成为有效的原子 - 这是在对象中无法完成的.)
你的Timer类绝对不是线程安全的:两个线程可以轻松地踩在彼此的数据上,并且没有什么可以阻止线程在计算持续时间时使用"陈旧"数据.
Stopwatch改为使用该类 - 这就是它的用途.不可否认,如果你想使用多个线程中的一个实例,你需要采取正常的步骤来确保安全,但总的来说你会处于更好的位置.诚然,这Stopwatch也远非完美 - 请参阅下面的问题和下面的评论以获取更多详细信息 - 但它至少是该类型的设计目标.(谁知道,它可能会被修复一段时间......)
Bil*_*ill 23
这是一个很好的讨论在这里是更侧重于机制和原因,为什么你的例子是不是线程安全的.
总而言之,首先,您的静态变量将被共享.如果你可以使它们成为局部变量,即使它们是静态方法的本地变量,它们仍然会得到自己的堆栈帧,因此是线程安全的.此外,如果您另外保护静态变量(即,此线程中其他人提到的锁和/或其他多线程编程技术),您还可以使示例静态类是线程安全的.
其次,因为您的示例不接受您修改的外部变量实例或其状态可能由另一个线程执行的外部变量实例,所以您的示例在这方面也是线程安全的.
Phi*_*ert 20
你的计时器类绝对不是线程安全的.您应该创建一个普通类,并在每次需要测量时间时实例化它:
Timer timer = new Timer();
timer.Start();
//...
timer.Stop();
decimal duration = timer.Duration();
Run Code Online (Sandbox Code Playgroud)
更好的是,有一个内置的.NET类正是这样做的:
Stopwatch sw = Stopwatch.StartNew();
sw.Stop();
TimeSpan duration = sw.Elapsed;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
41227 次 |
| 最近记录: |