Thread-Unsafe Threading Model

When you are dealing with multi-threaded code you will run into situations where some objects are not safe for concurrent use by several threads. Although these objects should theoretically not be accessed concurrently, it is very hard to proof that it never happens. And when it does happen, thread-unsafe data structures get corrupted, and symptoms may appear much later. These issues are typically very difficult to debug. So instead of relying on hope, it would be nice if the object threw an exception whenever it is accessed simultaneously by several threads. This is why we have the thread-unsafe threading model.

This topic contains the following sections:

Marking an object as thread-unsafe

To mark an object as thread-unsafe:

  1. When you don't want multiple threads to access a single instance of a given class you will want to configure InstanceLevelAspect thread safety. To do this, select "Apply threading model" from the smart tag on the class.

  2. Choose the "Apply thread-unsafe threading model" option.

    Concurrent Access Instance 2
  3. You will be prompted with a summary of the changes that will be made based on the configuration you selected in the wizard.

    Concurrent Access Instance 4
  4. PostSharp will download the Threading Pattern Library and add it to your project if that hasn't been done yet.

    Concurrent Access Instance 5
  5. Once the process has completed successfully you'll be presented with the final page of the wizard.

    Concurrent Access Instance 6
  6. You'll notice that only one change was made to your codebase. The [ThreadUnsafeAttribute] attribute was added to the class you were targeting.

    C#
    [ThreadUnsafe]
    class AverageCalculator
    {
        float sum;
        int count;
    
        public void AddSample(float n)
        {
            this.count++;
            this.sum += n;
        }
    
        public float GetAverage()
        {
            return this.sum / this.count;
        }
    }

Now when your application executes no two threads will be able to access a single instance of the AverageCalculator class at the same time. If two threads attempt to do this, the second thread will receive a ConcurrentAccessException. Without the exception, there would be a slight chance that internal sum or count fields would have invalid values because the increment operations would not be atomic.

See Also