Error During Dispose
Hello,
I am seeing the following intermittent error being thrown by SfUpload:
```
Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer: Warning: Unhandled exception rendering component: A task was canceled.
System.Threading.Tasks.TaskCanceledException: A task was canceled.
at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, JSCallType callType, Object[] args)
at Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime jsRuntime, String identifier, Object[] args)
at Syncfusion.Blazor.Internal.SfBaseUtils.InvokeMethod(IJSRuntime jsRuntime, String methodName, Object[] methodParams)
at Syncfusion.Blazor.SfBaseComponent.InvokeMethod(String methodName, Object[] methodParams)
at Syncfusion.Blazor.Inputs.SfUploader.CancelAsync(FileInfo[] fileData)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.<ProcessDisposalQueueInExistingBatch>g__GetHandledAsynchronousDisposalErrorsTask|99_0(Task result)
Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost: Error: Unhandled exception in circuit 'zGKmlLRoMcRrlxqOI4uu65Atfm4OK9p-rxS3MUOZJRU'.
System.Threading.Tasks.TaskCanceledException: A task was canceled.
at async ValueTask<TValue> Microsoft.JSInterop.JSRuntime.InvokeAsync<TValue>(long targetInstanceId, string identifier, JSCallType callType, object[] args)
at async ValueTask Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime jsRuntime, string identifier, params object[] args)
at async Task Syncfusion.Blazor.Internal.SfBaseUtils.InvokeMethod(IJSRuntime jsRuntime, string methodName, params object[] methodParams)
at async Task Syncfusion.Blazor.SfBaseComponent.InvokeMethod(string methodName, params object[] methodParams)
at async Task Syncfusion.Blazor.Inputs.SfUploader.CancelAsync(FileInfo[] fileData)
at async void Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessDisposalQueueInExistingBatch()+GetHandledAsynchronousDisposalErrorsTask(?
```
It appears to be occuring to the disposal of the control, and I have no control over it. Reporting it here for awareness or potential workarounds.
Thank you for your consideration.
Hi Mike,
We understand the scenario you're describing, during component disposal or rapid navigation in a Blazor Server application, an unhandled TaskCanceledException (originating from JS interop execution during component disposal) can cause the Blazor circuit to terminate, resulting in the reconnect overlay instead of graceful teardown.
We attempted to reproduce this behavior by simulating various upload scenarios, using Syncfusion versions V33.2.15. In our tests, Uploader component works without circuit disconnection in our environment.
Sample configuration:
- Project type: Blazor Server
- Nuget versions: v33.2.5
- .NET Version: 10
Validation details:
- Rendered Uploader in multiple pages and tested rapid switching between pages
- Tested component disposal during active uploads
- Tested component disposal immediately after upload completion
- Confirmed component disposal occurs properly during page navigation
- Single file upload (25 MB)
- Multi-file sequential uploads
- Auto-upload enabled and disabled scenarios
- Sequential and parallel upload modes
- Progressing/Uploading event callbacks
- Rapid page navigation during active uploads
- Programmatic navigation via NavigationManager
- Simulated network throttling (3G, 4G)
- Utilizing all the Uploader component events
Based on the error trace and our investigation, the TaskCanceledException is likely caused due to below reasons,
- Disposal Race Condition
- Circuit Disconnection During Interop
Note: Before proceeding to below solution, we kindly suggest you to update your nuget package to the latest version 33.2.15.
After upgrading, we kindly
suggest you to utilize the below code changes to overcome the mentioned
behavior,
Code Snippet:
|
@if (showUploader) { <SfUploader @ref="Uploader" AutoUpload="true" SequentialUpload="true"> … <UploaderEvents OnUploadStart="OnUploadStart" Progressing="OnProgress" BeforeRemove="BeforeRemove" OnFailure="OnFailure" OnRemove="OnRemove" Paused="Paused" Success="Success" ValueChange="ValueChange" /> </SfUploader> }
private SfUploader? Uploader; private bool showUploader = true; private string statusMessage = "Upload a 25MB file to auto-trigger dispose race..."; private Timer? disposeTimer; private bool hasActiveUpload; private Task OnUploadStart(UploadingEventArgs args) { statusMessage = "Upload started. Auto-dispose will trigger in 1 second..."; disposeTimer = new Timer(_ => TriggerDisposeRace(), null, 1000, Timeout.Infinite); return Task.CompletedTask; } private void OnFailure(FailureEventArgs args) { hasActiveUpload = false; } private void OnRemove(RemovingEventArgs args) { hasActiveUpload = false; } private void Success(SuccessEventArgs args) { hasActiveUpload = false; } private Task OnProgress(Syncfusion.Blazor.Inputs.ProgressEventArgs args) { if (args.LengthComputable && args.Total > 0) { decimal percentage = (args.Loaded / args.Total) * 100; statusMessage = $"Uploading... {percentage:F2}% complete ({args.Loaded}/{args.Total} bytes)"; } return Task.CompletedTask; } private void TriggerDisposeRace() { disposeTimer?.Dispose(); // Marshal to Blazor dispatcher _ = InvokeAsync(async () => { showUploader = false; StateHasChanged(); await Task.Delay(50); Nav.NavigateTo(Nav.Uri, forceLoad: true); }); } public async ValueTask DisposeAsync() { disposeTimer?.Dispose(); // Safe cancel to avoid unhandled TaskCanceledException during teardown if (Uploader is not null && hasActiveUpload) { try { await Uploader.CancelAsync(); } catch (TaskCanceledException) { } catch (JSDisconnectedException) { } catch (ObjectDisposedException) { } } } |
Workflow of code snippet:
- Upload starts → hasActiveUpload = true.
- Timer triggers TriggerDisposeRace().
- InvokeAsync(...) safely updates UI (showUploader = false) and navigates.
- Component disposal runs DisposeAsync().
- CancelAsync() is called inside try/catch.
- If circuit is already disconnecting, TaskCanceledException is caught and ignored.
- Result: no unhandled disposal-time exception.
We have attached the validated sample for your reference,
Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/BlazorWebApp
GIF:
If you still face this issue
after applying the safe-disposal handling,In order to assist us in identifying
the problem and providing a better solution, we kindly request that you share
the additional details mentioned below:
- Syncfusion Blazor NuGet version (exact version number)
- .NET version and Blazor hosting model (Server/WebAssembly)
- Exact reproduction steps
- Frequency (always/intermittent, e.g., 2 out of 10 times)
- Whether issue happens during:
- page navigation
- tab close/refresh
- network interruption
- Are you experiencing this issue on a specific platform, or does it occurring across all platforms (e.g., Windows, macOS, Android, iPadOS, iOS)?
- Please share a runnable sample that demonstrates the issue you are experiencing. You may also modify the previously shared sample to reflect your specific scenario. This will help us understand how the component is integrated and handled in your project.
- File Upload component events you have utilized and customizations you have made.
- A video illustrating the issue.
Feel free to share us the above requested details and get back to us if you need further assistance.
Regards,
Jafar Ali S
Hi Jafar,
Thank you for your thoughtful reply. Please be aware that this cancellation is not occurring in my code, and I am not calling it in any way. This happens when a component is disposed of, and your disposal method is called in your code. I also cannot consistently reproduce it, and it occurs intermittently and unexpectedly in my own code. It is being called by your control through its own disposal process. Additionally, the OperationCanceledException is being thrown by the JSInterop.Invoke via your CancelAsync.
Can you please confirm that you are accounting for cancellation in CancelAsync during dispose?
I am using 33.2.13 here. I will upgrade to 33.2.15 and continue to monitor this issue.
- 2 Replies
- 2 Participants
-
MI Mike-E
- Jun 28, 2026 08:56 AM UTC
- Jun 30, 2026 06:44 AM UTC