Open sandboxFocusImprove this doc

THR025: Type Has No Threading Model

Severity Warning
Reported by PostSharp.Patterns.Threading
Message Thread-safety policy: type <Type> must be assigned to a threading model or marked as [ExplicitlySynchronized].

Cause

When you add the ThreadSafetyPolicy attribute to an assembly, PostSharp checks every class of the assembly, including nested classes, and reports THR025 for each class that it does not consider thread-safe. A class is thread-safe for the policy when:

The policy does not check structs, custom attribute classes and compiler-generated types. THR025 is a warning: the policy reminds you to choose a threading model for each class, but does not change the code.

In the following example, the ShoppingCart class has two mutable fields and no threading model.

using System;
using PostSharp.Patterns.Threading;

[assembly: ThreadSafetyPolicy]

namespace Errors.THR025_Error;

// The class has instance fields but no threading model, so the policy reports it.
public class ShoppingCart
{
    private int itemCount;
    private decimal total;

    public void AddItem( decimal price )
    {
        this.itemCount++;
        this.total += price;
    }

    public string Describe() => $"{this.itemCount} items, total {this.total}";
}

public static class Program
{
    public static void Main()
    {
        var cart = new ShoppingCart();
        cart.AddItem( 10 );
        cart.AddItem( 15 );
        Console.WriteLine( cart.Describe() );
    }
}
warning THR025: THR025_Error.cs(9,14): Thread-safety policy: type Errors.THR025_Error.ShoppingCart must be assigned to a threading model or marked as [ExplicitlySynchronized].

Resolution

In the following example, the SynchronizedAttribute threading model makes ShoppingCart thread-safe.

using System;
using PostSharp.Patterns.Threading;

[assembly: ThreadSafetyPolicy]

namespace Errors.THR025_Fixed;

// The [Synchronized] threading model makes the class thread-safe, so the policy accepts it.
[Synchronized]
public class ShoppingCart
{
    private int itemCount;
    private decimal total;

    public void AddItem( decimal price )
    {
        this.itemCount++;
        this.total += price;
    }

    public string Describe() => $"{this.itemCount} items, total {this.total}";
}

public static class Program
{
    public static void Main()
    {
        var cart = new ShoppingCart();
        cart.AddItem( 10 );
        cart.AddItem( 15 );
        Console.WriteLine( cart.Describe() );
    }
}
2 items, total 25

See Also

Reference

ThreadSafetyPolicy
ExplicitlySynchronizedAttribute
SynchronizedAttribute

Other Resources

Making a Whole Project or Solution Thread Safe
Writing Thread-Safe Code with Threading Models