Repository: AvaloniaUI/Avalonia
File: src/Avalonia.Base/Utilities/WeakEvent.cs (C#)

Code before:
/// </summary>
public sealed class WeakEvent<TSender, TEventArgs> : WeakEvent where TSender : class
{
    private readonly Func<TSender, EventHandler<TEventArgs>, Action> _subscribe;

    private readonly ConditionalWeakTable<object, Subscription> _subscriptions = new();

    internal WeakEvent(
        Action<TSender, EventHandler<TEventArgs>> subscribe,
        Action<TSender, EventHandler<TEventArgs>> unsubscribe)
    {
        _subscribe = (t, s) =>
        {
            subscribe(t, s);
            return () => unsubscribe(t, s);
        };
    }

    internal WeakEvent(Func<TSender, EventHandler<TEventArgs>, Action> subscribe)
    {
        _subscribe = subscribe;
    }

    public void Subscribe(TSender target, IWeakEventSubscriber<TEventArgs> subscriber)
    {
        SpinWait? spinWait = null;
        while (true)
        {
            var subscription = _subscriptions.GetValue(target, _ => new Subscription(this, target));
            if (subscription.Add(subscriber))
                break;
            (spinWait ??= default).SpinOnce();
        }
    }

    public void Unsubscribe(TSender target, IWeakEventSubscriber<TEventArgs> subscriber)
    {
        if (_subscriptions.TryGetValue(target, out var subscription))
            subscription.Remove(subscriber);
    }

    private sealed class Subscription
    {
        private readonly WeakEvent<TSender, TEventArgs> _ev;
        private readonly TSender _target;
        private readonly Action _compact;
        private readonly WeakHashList<IWeakEventSubscriber<TEventArgs>> _list = new();
        private readonly object _lock = new();
        private Action? _unsubscribe;
        private bool _compactScheduled;
        private bool _destroyed;

Review comment (suggestion):
This isn't correct, the `SpinWait` returned from `Nullable<SpinWait>` is a copy, meaning no state gets persisted. You might as well initialize the `SpinWait` directly here, it's a single int in size.

Code after:
/// </summary>
public sealed class WeakEvent<TSender, TEventArgs> : WeakEvent where TSender : class
{
    private readonly Func<TSender, EventHandler<TEventArgs>, Action> _subscribe;
    private readonly ConditionalWeakTable<TSender, Subscription> _subscriptions = new();
    private readonly ConditionalWeakTable<TSender, Subscription>.CreateValueCallback _createSubscription;

    internal WeakEvent(
        Action<TSender, EventHandler<TEventArgs>> subscribe,
        Action<TSender, EventHandler<TEventArgs>> unsubscribe)
    {
        _subscribe = (t, s) =>
        {
            subscribe(t, s);
            return () => unsubscribe(t, s);
        };
        _createSubscription = CreateSubscription;
    }

    internal WeakEvent(Func<TSender, EventHandler<TEventArgs>, Action> subscribe)
    {
        _subscribe = subscribe;
        _createSubscription = CreateSubscription;
    }

    public void Subscribe(TSender target, IWeakEventSubscriber<TEventArgs> subscriber)
    {
        var spinWait = default(SpinWait);
        while (true)
        {
            var subscription = _subscriptions.GetValue(target, _createSubscription);
            if (subscription.Add(subscriber))
                break;
            spinWait.SpinOnce();
        }
    }

    public void Unsubscribe(TSender target, IWeakEventSubscriber<TEventArgs> subscriber)
    {
        if (_subscriptions.TryGetValue(target, out var subscription))
            subscription.Remove(subscriber);
    }

    private Subscription CreateSubscription(TSender key) => new(this, key);

    private sealed class Subscription
    {
        private readonly WeakEvent<TSender, TEventArgs> _ev;
        private readonly TSender _target;
        private readonly Action _compact;
        private readonly WeakHashList<IWeakEventSubscriber<TEventArgs>> _list = new();