4
votes

I implemented a debounce on input with CancellationTokenSource in Blazor server side app (.net core 3.0).

It works well with input delay as expected, but always writes errors in Debug Output, when typing:

Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Components.dll

and when fast typing:

Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll

Do you have any ideas how to fix it?

You can find the implementation here: https://blazorfiddle.com/s/ij9l55ne

Main page:

@page "/"
@using System.Threading
@using System.Threading.Tasks

<MyChildComponent OnTyping="async e => await OnTypingAsync(e)"/>
<div>@result</div>

@code {
    string result;

    public async Task OnTypingAsync(string myText)
    {
        await Task.Delay(1);//call GetDataAsync(myText) method

        result = myText;
        await InvokeAsync(StateHasChanged);
    }
}

Child component:

@using System.Threading
@using System.Threading.Tasks

<input type="text" @oninput="async e => await OnInput(e)" />

@code {
    [Parameter] public EventCallback<string> OnTyping { get; set; }

    CancellationTokenSource Cts = new CancellationTokenSource();
    CancellationToken Ct;

    public async Task OnInput(ChangeEventArgs e)
    {
        Cts.Cancel();
        Cts = new CancellationTokenSource();
        Ct = Cts.Token;

        await Task.Delay(500, Ct).ContinueWith(async task =>
        {
            if (!task.IsCanceled) {
                await OnTyping.InvokeAsync(e.Value.ToString());
            }
        }, Ct);
    }
}
1
Sorry i can't reproduce the error can you please check your ChildComponent implementation because i am confused, you called Cts.Cancel() function after immediate you instantiate CancellationTokenSource once again. As per my knowledge Blazor is not a state less, Server and Client should be in connected state. - Mofaggol Hoshen
Cts.Cancel() cancels previous one, that's debounce implementation. These errors you can see in Debug Output window - Ka Marius
I sugest to open an issue on github repo - agua from mars
Have you try to deploy in Release mode and check if you still see this error in log ? - agua from mars
I opened issue in github: github.com/aspnet/AspNetCore/issues/16524 the same is in Debug and Release modes, github repo for reproduce: github.com/Marius-Kazlauskas/blazor-debounce-bug-demonstration - Ka Marius

1 Answers

2
votes

javiercn provides good idea how to solve this problem on github issue registered by me: https://github.com/aspnet/AspNetCore/issues/16524#issuecomment-546847682

  • You need to always catch OperationCanceledException when using cancellation tokens.
  • You should avoid using continue with in your method as you are not capturing the SynchronizationContext and that's going to produce errors when you try to update the UI from the continuation callback.