Cysharp / R3

The new future of dotnet/reactive and UniRx.
MIT License
1.72k stars 70 forks source link

Unexpected behavior in ReactiveProperty #166

Closed gif-hara closed 4 months ago

gif-hara commented 4 months ago

I have confirmed that the A subscription does not work correctly when I run the following code.

The operating environment is as follows Unity 2022.3.16f1 Unity 2023.2.3f1

using System.Threading;
using R3;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    void Start()
    {
        var count = 0;
        var r = new ReactiveProperty<int>(count);
        var ctsA = new CancellationTokenSource();
        var ctsB = new CancellationTokenSource();
        var ctsC = new CancellationTokenSource();
        r.Subscribe(x => Debug.Log($"A = {x}")).RegisterTo(ctsA.Token);
        r.Subscribe(x => Debug.Log($"B = {x}")).RegisterTo(ctsB.Token);
        r.Subscribe(x => Debug.Log($"C = {x}")).RegisterTo(ctsC.Token);
        ctsA.Cancel();
        ctsA.Dispose();
        Debug.Log("A disposed");
        ctsA = new CancellationTokenSource();
        r.Subscribe(x => Debug.Log($"A = {x}")).RegisterTo(ctsA.Token);
        Debug.Log("A re-registered");
        ctsA.Cancel();
        ctsA.Dispose();
        Debug.Log("A disposed");
        ctsA = new CancellationTokenSource();
        r.Subscribe(x => Debug.Log($"A = {x}")).RegisterTo(ctsA.Token);
        Debug.Log("A re-registered");
        r.Value = ++count;
        r.Value = ++count;

        // Expected operation:
        // A = 0
        // B = 0
        // C = 0
        // A disposed
        // A = 0
        // A re-registered
        // A disposed
        // A = 0
        // A re-registered
        // A = 1
        // B = 1
        // C = 1
        // A = 2
        // B = 2
        // C = 2

        // However, the actual operation is:
        // A = 0
        // B = 0
        // C = 0
        // A disposed
        // A = 0
        // A re-registered
        // A disposed
        // A = 0
        // A re-registered
        // B = 1
        // C = 1
        // B = 2
        // C = 2
    }
}
gif-hara commented 4 months ago

We have confirmed that this also occurs in R3 version 1.1.8...!

neuecc commented 4 months ago

thank you, I've fixed in 1.1.9 and added your code as test(after re-registered, expected is B = 1, C = 1, A = 1, B = 2, C = 2, A = 2).

gif-hara commented 4 months ago

Ah, I was wrong about the expectations! Thank you very much!