stride3d/stride · error · ArgumentNullException

lockSlim

Error message

lockSlim

What it means

HeightfieldColliderShape.HeightArrayLock is a scoped lock helper wrapping a ReaderWriterLockSlim. It throws ArgumentNullException when the passed lockSlim is null, since unlocking later would be impossible and the lock object is mandatory.

Solutions

  1. Ensure the HeightfieldColliderShape is fully constructed (its readerWriterLockSlim field initialized) before acquiring a HeightArrayLock.
  2. Pass a non-null ReaderWriterLockSlim instance when constructing HeightArrayLock directly.
  3. If using the public Lock* APIs on the shape, don't construct the lock handle manually.

Example fix

// before
var l = new HeightfieldColliderShape.HeightArrayLock(LockTypes.Read, null);
// after
var l = new HeightfieldColliderShape.HeightArrayLock(LockTypes.Read, shape.LockSlim);
Defensive patterns

Strategy: type-guard

Validate before calling

if (lockSlim == null) throw new InvalidOperationException("ReaderWriterLockSlim must be initialized before locking.");

Type guard

bool CanLock(ReaderWriterLockSlim l) => l != null;

Try / catch

try { var l = new HeightArrayLock(LockTypes.Read, lockSlim); }
catch (ArgumentNullException) { /* lazily initialize the lock */ }

Prevention

When it happens

Trigger: Constructing HeightArrayLock(lockType, null) — typically only reachable via internal misuse, since the ReaderWriterLockSlim is a private field of HeightfieldColliderShape initialized with the shape.

Common situations: Custom subclasses or refactored code that constructs the lock handle before the heightfield's lock is initialized (e.g. in a partially constructed object).

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/29c32f54996e8edc. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Physics/Shapes/HeightfieldColliderShape.cs:180

    {
        return new HeightArrayLock(HeightArrayLock.LockTypes.ReadWrite, lockSlim);
    }

    public class HeightArrayLock : IDisposable
    {
        public enum LockTypes
        {
            Read = 0,
            ReadWrite = 1,
        }

        private readonly ReaderWriterLockSlim readerWriterLockSlim;

        internal HeightArrayLock(LockTypes lockType, ReaderWriterLockSlim lockSlim)
        {
            if (lockSlim == null)
            {
                throw new ArgumentNullException(nameof(lockSlim));
            }

            readerWriterLockSlim = lockSlim;

            switch (lockType)
            {
                case LockTypes.Read:
                    readerWriterLockSlim.EnterReadLock();
                    break;
                case LockTypes.ReadWrite:
                    readerWriterLockSlim.EnterWriteLock();
                    break;
                default:
                    throw new ArgumentException($"{ nameof(lockType) } is invalid type");
            }
        }

        public void Unlock()

View on GitHub (pinned to 96fad776d2)