简体   繁体   中英

MSpec: How to make static variables thread-safe?

I'm using MSpec for my latest project, and overall I'm really happy with it. However, I do have an issue with concurrency when my tests run in paralel and I'm wondering if anybody has run into this issue or, even better, has a solution?

MSpec heavily relies on static methods and variables to work.

Now it appears when I define static variables in my base classes, that are used by multiple test classes, and I run my tests in paralel, that they share the same static variables and thus interfere with eachother.

I'm using both NCrunch and Resharper as my testrunners and I'm experiencing the problem in both.

Anybody familiar with this problem?

Firstly, I would recommend reading the Thead Safety Guidelines on MSDN . This will give you a good overview of how and why to make methods thread safe in C#.

The following rules outline the design guidelines for implementing threading:

  • Avoid providing static methods that alter static state. In common server scenarios, static state is shared across requests, which means multiple threads can execute that code at the same time. This opens up the possibility for threading bugs. Consider using a design pattern that encapsulates data into instances that are not shared across requests.
  • ... Adding locks to create thread-safe code decreases performance, increases lock contention, and creates the possibility for deadlock bugs to occur
  • Be aware of method calls in locked sections. Deadlocks can result when a static method in class A calls static methods in class B and vice versa. If A and B both synchronize their static methods, this will cause a deadlock. You might discover this deadlock only under heavy threading stress.
  • Be aware of issues with the lock statement (SyncLock in Visual Basic). It is tempting to use the lock statement to solve all threading problems. However, the System.Threading.Interlocked Class is superior for updates that must be atomic ...

As a general note a methodology which I prefer to use (where possible) is to make a method (static or otherwise) immutable . To do this, all variables should be local (created locally on the stack, or passed in as parameters to a method). By ensuring only local variables are used, or member variables are immutable each thread will operate in its own compartment and changes to variables will not affect another thread. This is a methodology I have used extensively in .NET simulation software to allow lock-less and therefore high performance multithreading in C#.

Alternatively, if variables must be member variables and mutable access to them may be protected by lock keywords. Be careful with the use of lock will cause context switching (slow down) and introduces the possibility of a deadlock situation. It also doesn't gaurantee thread safety as the use of lock must protect against the specific scenario you are trying to prevent.

For further reading I would suggest looking these related questions which describe thread safety and immutability in C#:

Best regards,

Static fields are not thread-safe by default. To make them thread-safe you can decorate them with the [ThreadStatic] attribute.

Have a look at ThreadStaticAttribute Class at MSDN for more info.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM