如果我有一个共享System.Diagnostics.Stopwatch
实例,多个线程可以shared.ElapsedTicks
以安全的方式调用并获得准确的结果吗?
GetTimeStamp()
以这种方式使用 Stopwatch 的共享实例和使用静态方法在线程安全/准确性方面有什么区别吗?
我正在测量大约 180 毫秒的间隔,并发现使用共享实例给了我更大的结果分布,包括比我预期的更短的重要数字。
这台机器有多个 CPU(2 * Intel X5550 物有所值)
如果我有一个共享System.Diagnostics.Stopwatch
实例,多个线程可以shared.ElapsedTicks
以安全的方式调用并获得准确的结果吗?
GetTimeStamp()
以这种方式使用 Stopwatch 的共享实例和使用静态方法在线程安全/准确性方面有什么区别吗?
我正在测量大约 180 毫秒的间隔,并发现使用共享实例给了我更大的结果分布,包括比我预期的更短的重要数字。
这台机器有多个 CPU(2 * Intel X5550 物有所值)
来自MSDN:
不保证任何实例成员都是线程安全的。
查看源代码,它是线程安全的,但你不能使用Stop()
:Reset()
和Restart()
.
所以,如果你启动一个共享实例,不修改它并且只调用ElapsedXXX
属性,你应该没问题。
查看源代码,它不是线程安全的。
您可以使用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);
}