在Blazor服务器端使用CancellationTokenSource消除实现

时间:2019-10-26 05:48:31

标签: blazor blazor-server-side cancellationtokensource debouncing

我在Blazor服务器端应用程序(.net core 3.0)中使用CancellationTokenSource在输入上实现了反跳。

它可以按预期与输入延迟一起很好地工作,但是总是在“调试输出”中写入错误, 键入时:

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

以及快速键入时:

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

您是否有解决办法?

您可以在此处找到实现: https://blazorfiddle.com/s/ij9l55ne

主页:

@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);
    }
}

子组件:

@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 个答案:

答案 0 :(得分:0)

javiercn提供了一个好主意,如何解决我注册的github问题上的这个问题: https://github.com/aspnet/AspNetCore/issues/16524#issuecomment-546847682

  • 使用取消令牌时,您需要始终捕获OperationCanceledException。
  • 您应该避免在方法中使用continue,因为您没有捕获SynchronizationContext,并且在尝试从延续回调中更新UI时会产生错误。