Skip to content

Why there is not an UniCancellationTokenSource? #686

@labbbirder

Description

@labbbirder

Hi, there ✋. I noticed that most usage of CancellationTokenSource can still produce gc, even the documented TimeoutController.

CancellationTokenSource will always alloc without TryReset()

As to the version of CLR in Unity, the method CancellationTokenSource::TryReset() is not exposed, which grant ability to UnregisterAll() and reuse a token source who is not cancelled.

Without TryReset(), the only way to produce no GC with cancellable tasks is not use CancellationTokenSource.

TimeoutController will leak with Register()

I reviewed the code of TimeoutController, it will work well unless task complete first and Register() is called.

The follow illustration will leak repeatly:

const int ParallelCount = 100;

TimeoutController timeoutController = new();
UniTask[] tasks = new UniTask[ParallelCount];

async UniTaskVoid TestMethod()
{
    var ct = timeoutController.Timeout(1000);
    foreach (var i in ..ParallelCount)
    {
        // use cancelImmediately to Register() on CancellationTokenSource
        tasks[i] = UniTask.Yield(cancellationToken: ct, cancelImmediately: true);
    }

    foreach (var task in tasks)
    {
        await task;
    }

    // reused without reset CancellationTokenSource._registrations
    timeoutController.Reset();
}

async void Update()
{
    TestMethod().Forget();
}

Do you have any plan for an implement of something like UniCancellationTokenSource as an Alternative to CancellationTokenSource?

Thx. ❤️

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions