是Stopwatch.ElapsedTicks线程安全吗?

时间:2011-07-12 13:00:34

标签: c# stopwatch

如果我有一个共享System.Diagnostics.Stopwatch实例,多个线程可以安全地调用shared.ElapsedTicks并获得准确的结果吗?

以这种方式使用秒表的共享实例和使用静态GetTimeStamp()方法之间的线程安全性/准确性方面是否存在差异?

我正在测量大约180毫秒的间隔,发现使用共享实例会给我更大的结果,包括比我预期的更短的数字。

该机器有多个CPU(2 *英特尔X5550,它的价值)

5 个答案:

答案 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的等价刻度。

本来可以作为其他答案的评论,但我的声誉不高:/

相关问题