There are some heavy JS objects I would like to clean up using the dispose method.
I use IJSObjectReference to call JS code.
The code:
public partial class BlazorComponent : IAsyncDisposable, IDisposable
{
private bool _isDisposed;
private IJSObjectReference? _jsModule;
// ...
public async ValueTask DisposeAsync()
{
await DisposeAsync(true);
GC.SuppressFinalize(this);
}
public void Dispose()
{
DisposeAsync(true); // Won't be awaited
GC.SuppressFinalize(this);
}
private async ValueTask DisposeAsync(bool disposing)
{
if (_isDisposed)
return;
if (_jsModule is not null)
await _jsModule.InvokeVoidAsync("deleteHeavyObject");
if (disposing)
{
if (_jsModule is not null)
await _jsModule.DisposeAsync();
}
_isDisposed = true;
}
~BlazorComponent()
{
DisposeAsync(false); // Won't be awaited
}
}
The IJSObjectReference only implements IAsyncDisposable and you can only call JS methods via async methods.
What is the best practice to deal with this situation?
I could do DisposeAsync(...).AsTask().Wait() or I could just not implement IDispose and the deconstructor because it looks like in Blazor Dispose/DisposeAsync gets called regardless of the GC?
IDisposableat all?IAsyncDisposable.DisposeAsyncimplementation regardless of any GC.IAsyncDisposable, then your type should only implementIAsyncDisposable. Then you don't have any problems.