Abort a long-running JavaScript function (#25346)
parent
6f78cd3e9a
commit
752ad73861
|
@ -720,6 +720,94 @@ In the following example, the `nonFunction` JS function doesn't exist. When the
|
|||
|
||||
[!code-csharp[](~/blazor/samples/6.0/BlazorSample_WebAssembly/Pages/call-js-from-dotnet/CallJsExample11.razor?highlight=28)]
|
||||
|
||||
## Abort a long-running JavaScript function
|
||||
|
||||
Use a JS [AbortController](https://developer.mozilla.org/docs/Web/API/AbortController) with a <xref:System.Threading.CancellationTokenSource> in the component to abort a long-running JavaScript function from C# code.
|
||||
|
||||
The following JS `Helpers` class contains a simulated long-running function, `longRunningFn`, to count continuously until the [`AbortController.signal`](https://developer.mozilla.org/docs/Web/API/AbortController/signal) indicates that [`AbortController.abort`](https://developer.mozilla.org/docs/Web/API/AbortController/abort) has been called. The `sleep` function is for demonstration purposes to simulate slow execution of the long-running function and wouldn't be present in production code. When a component calls `stopFn`, the `longRunningFn` is signalled to abort via the `while` loop conditional check on [`AbortSignal.aborted`](https://developer.mozilla.org/docs/Web/API/AbortSignal/aborted).
|
||||
|
||||
Add the following JS code inside the closing `</body>` tag of `wwwroot/index.html` (Blazor WebAssembly) or `Pages/_Layout.cshtml` (Blazor Server):
|
||||
|
||||
```html
|
||||
<script>
|
||||
class Helpers {
|
||||
static #controller = new AbortController();
|
||||
|
||||
static async #sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
static async longRunningFn() {
|
||||
var i = 0;
|
||||
while (!this.#controller.signal.aborted) {
|
||||
i++;
|
||||
console.log(`longRunningFn: ${i}`);
|
||||
await this.#sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
static stopFn() {
|
||||
this.#controller.abort();
|
||||
console.log('longRunningFn aborted!');
|
||||
}
|
||||
}
|
||||
|
||||
window.Helpers = Helpers;
|
||||
</script>
|
||||
```
|
||||
|
||||
The following `CallJsExample12` component:
|
||||
|
||||
* Invokes the JS function `longRunningFn` when the **`Start Task`** button is selected. A <xref:System.Threading.CancellationTokenSource> is used to manage the execution of the long-running function. <xref:System.Threading.CancellationToken.Register%2A?displayProperty=nameWithType> sets a JS interop call delegate to execute the JS function `stopFn` when the <xref:System.Threading.CancellationTokenSource.Token?displayProperty=nameWithType> is cancelled.
|
||||
* When the **`Cancel Task`** button is selected, the <xref:System.Threading.CancellationTokenSource.Token?displayProperty=nameWithType> is cancelled with a call to <xref:System.Threading.CancellationTokenSource.Cancel%2A>.
|
||||
* The <xref:System.Threading.CancellationTokenSource> is disposed in the `Dispose` method.
|
||||
|
||||
`Pages/CallJsExample12.razor`:
|
||||
|
||||
```razor
|
||||
@page "/call-js-example-12"
|
||||
@inject IJSRuntime JS
|
||||
|
||||
<h1>Cancel long-running JS interop</h1>
|
||||
|
||||
<p>
|
||||
<button @onclick="StartTask">Start Task</button>
|
||||
<button @onclick="CancelTask">Cancel Task</button>
|
||||
</p>
|
||||
|
||||
@code {
|
||||
private CancellationTokenSource? cts;
|
||||
|
||||
private async Task StartTask()
|
||||
{
|
||||
cts = new CancellationTokenSource();
|
||||
cts.Token.Register(() => JS.InvokeVoidAsync("Helpers.stopFn"));
|
||||
|
||||
await JS.InvokeVoidAsync("Helpers.longRunningFn");
|
||||
}
|
||||
|
||||
private void CancelTask()
|
||||
{
|
||||
cts?.Cancel();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
cts?.Cancel();
|
||||
cts?.Dispose();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
A browser's [developer tools](https://developer.mozilla.org/docs/Glossary/Developer_Tools) console indicates the execution of the long-running JS function after the **`Start Task`** button is selected and when the function is aborted after the **`Cancel Task`** button is selected:
|
||||
|
||||
```console
|
||||
longRunningFn: 1
|
||||
longRunningFn: 2
|
||||
longRunningFn: 3
|
||||
longRunningFn aborted!
|
||||
```
|
||||
|
||||
## Additional resources
|
||||
|
||||
* <xref:blazor/js-interop/call-dotnet-from-javascript>
|
||||
|
|
Loading…
Reference in New Issue