如果我有一个共享System.Diagnostics.Stopwatch
实例,多个线程可以安全地调用shared.ElapsedTicks
并获得准确的结果吗?
以这种方式使用秒表的共享实例和使用静态GetTimeStamp()
方法之间的线程安全性/准确性方面是否存在差异?
我正在测量大约180毫秒的间隔,发现使用共享实例会给我更大的结果,包括比我预期的更短的数字。
该机器有多个CPU(2 *英特尔X5550,它的价值)
答案 0 :(得分:10)
来自MSDN:“不保证任何实例成员都是线程安全的。”
答案 1 :(得分:6)
您可以使用https://msdn.microsoft.com/en-us/library/dd642243(v=vs.110).aspx
ThreadLocal<T>
像这样:
ThreadLocal<Random> _localRandom = new ThreadLocal<Random>(() => new Random());
ThreadLocal<Stopwatch> _localStopwatch = new ThreadLocal<Stopwatch>(() => new Stopwatch());
public void SomeTest()
{
Action someAction = () =>
{
_localStopwatch.Value.Reset();
_localStopwatch.Value.Start();
Thread.Sleep(_localRandom.Value.Next(100, 500));
_localStopwatch.Value.Stop();
Debug.Print(_localStopwatch.Value.Elapsed.TotalMilliseconds.ToString(CultureInfo.InvariantCulture));
};
var actions = Enumerable.Range(0, 1000).Select(i => someAction).ToArray();
Parallel.Invoke(new ParallelOptions {MaxDegreeOfParallelism = Environment.ProcessorCount}, actions);
}
答案 2 :(得分:5)
查看源代码,它不是线程安全的。
答案 3 :(得分:0)
Looking at the source code,这是线程安全的,但您不得使用:Stop()
,Reset()
和Restart()
。
因此,如果您启动一个共享实例,不对其进行修改,而仅调用ElapsedXXX
属性,就可以了。
答案 4 :(得分:0)
要在此处添加其他答案,尽管此属性是安全的,只要您不调用Start()
,Reset()
或Stop()
方法,请务必注意例如,如果您使用记号进行算术运算,然后将值传递到TimeSpan
构造函数中,则一个stopWatch.ElapsedTicks
记号不等于TimeSpan
记号,如here.所述得到您想要使用stopWatch.Elapsed.Ticks
的等价刻度。
本来可以作为其他答案的评论,但我的声誉不高:/