是Stopwatch.ElapsedTicks线程安全吗?

Rob*_*Rob 8 c# stopwatch

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

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

我测量的180ms时左右间隔,并且发现使用共享实例是给我结果的价差较大,包括更短,比我期望一个显著数量.

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

Mag*_*nus 10

来自MSDN:"不保证任何实例成员都是线程安全的."

  • +1,你的答案是正确的..添加“Stopwatch.GetTimestamp();”是线程安全的,因为它是静态的。 (2认同)

xme*_*eko 7

查看源代码它是线程安全的,但您一定不能使用: Stop(), Reset()and Restart()

所以,如果你启动一个共享实例,不修改它并且只调用ElapsedXXX属性,你应该没问题。

  • 虽然只要您不调用“Start()”、“Reset()”或“Stop()”方法,此属性就是安全的,但需要注意的是,如果您使用刻度进行算术,然后传递将值放入“TimeSpan”构造函数中,例如,一个“stopWatch.ElapsedTicks”Tick 不等于“TimeSpan”Ticks,如下所述:http://geekswithblogs.net/BlackRabbitCoder/archive/2012/01/12/c .net-little-pitfalls-stopwatch-ticks-are-not-timespan-ticks.aspx。要获得等效的刻度,您需要使用“stopWatch.Elapsed.Ticks”。 (3认同)
  • 使用 .NET 4.8 在 64 位计算机上进行的实证测试似乎证实了 ElapsedXXX 属性的线程安全性。 (2认同)

Den*_*nis 6

你可以使用https://msdn.microsoft.com/en-us/library/dd642243(v=vs.110).aspx

ThreadLocal<T> 
Run Code Online (Sandbox Code Playgroud)

像这样:

    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);
    }
Run Code Online (Sandbox Code Playgroud)


SLa*_*aks 5

查看源代码,它不是线程安全的.