Issues with RadzenGrid.Dispose

I appear to be running into issues with this method, unfortunately. In my case, the following exception is being thrown whenever the page loads and/or I do a refresh:

System.InvalidOperationException: 'JavaScript interop calls cannot be issued at this time. This is because the component is being statically rendererd. When prerendering is enabled, JavaScript interop calls can only be performed during the OnAfterRenderAsync lifecycle method.'

The challenge here is that it seems a call to JSRuntime.InvokeVoidAsync is being called, which is producing the exception once the task is executed. As this is an asynchronous method being called in a synchronous method, this execution is deferred, so there is no easy way to try-catch it.

Additionally, I am also getting another similar problem in RadzenGrid.RemoveColumn call:

System.ObjectDisposedException: 'Cannot process pending renders after the renderer has been disposed.
Object name: 'Renderer'.'

The same issue occurs here: the exception occurs when the task is executed and not at the time the containing method is (synchronously) executed. In this case a try-catch is applied to the this.InvokeAsync call, but again since this is a Task, the execution is deferred, and the exception is thrown at the time the Task is executed, which means the try/catch is ignored altogether.

I hate to suggest it, but if asynchronous calls are being made in synchronous methods, perhaps the use of IAsyncDisposable would be a better path. The reason why I hate suggesting this is that I despise bifurcating code, but alas that is the nature of the environment we find ourselves in these days.

Anyways, diatribe aside, the following is what I see in the Debug output window whenever I load the page with a RadzenGrid:

Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Components.Server.dll
JavaScript interop calls cannot be issued at this time. This is because the component is being statically rendererd. When prerendering is enabled, JavaScript interop calls can only be performed during the OnAfterRenderAsync lifecycle method.

Exception thrown: 'System.InvalidOperationException' in Microsoft.JSInterop.dll
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Components.Server.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.JSInterop.dll
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Components.Server.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.JSInterop.dll
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Components.Server.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.JSInterop.dll
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Cannot process pending renders after the renderer has been disposed.

Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Cannot process pending renders after the renderer has been disposed.

Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll

And after a refresh:

Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Components.Server.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.JSInterop.dll
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Components.Server.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.JSInterop.dll
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Components.Server.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.JSInterop.dll
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Components.Server.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.JSInterop.dll
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll
[2020-10-11T15:34:52.950Z] Error: Circuit has been shut down due to error.
[2020-10-11T15:34:52.953Z] Information: Connection disconnected.
Error: Cannot send data if the connection is not in the 'Connected' State.
    at e.send (https://localhost:44306/_framework/blazor.server.js:1:43256)
    at e.sendMessage (https://localhost:44306/_framework/blazor.server.js:1:16302)
    at e.sendWithProtocol (https://localhost:44306/_framework/blazor.server.js:1:16364)
    at e.send (https://localhost:44306/_framework/blazor.server.js:1:16555)
    at Object.endInvokeJSFromDotNet (https://localhost:44306/_framework/blazor.server.js:8:105810)
    at https://localhost:44306/_framework/blazor.server.js:8:31674
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
[2020-10-11T15:34:53.655Z] Information: Normalizing '_blazor' to 'https://localhost:44306/_blazor'.
[2020-10-11T15:34:53.799Z] Information: WebSocket connected to wss://localhost:44306/_blazor?id=yi7mJNfzvXcT0JB_P5IsOQ.

Additionally, after a refresh, since there is a server disconnection, a notification is briefly shown in the client browser:

An unhandled exception has occurred. See browser development tools for details. Reload

FWIW, the following workaround works for me, handling the errors and removing the server disconnection notification:

	public class DataGrid<T> : RadzenGrid<T>
	{
		public override void Dispose()
		{
			InvokeAsync(Disposing);
		}

		async ValueTask InvokeVoid(string name, object parameter)
		{
			try
			{
				await JSRuntime.InvokeVoidAsync(name, parameter);
			}
			catch
			{
				// Should log, etc.
			}
		}

		async Task Disposing()
		{
			if (ContextMenu.HasDelegate)
				await InvokeVoid("Radzen.removeContextMenu", UniqueID);
			if (MouseEnter.HasDelegate)
				await InvokeVoid("Radzen.removeMouseEnter", UniqueID);
			if (MouseLeave.HasDelegate)
			{
				await InvokeVoid("Radzen.removeMouseLeave", UniqueID);

				var columns = GetType().GetField("columns")
				                       .Verify()
				                       .GetValue(this)
				                       .Verify()
				                       .To<List<RadzenGridColumn<T>>>();

				var id = $"popup{UniqueID}";

				foreach (var column in columns.Where(c => c.Visible))
				{
					await InvokeVoid("Radzen.destroyPopup", id + column.GetFilterProperty());
				}
			}
		}
	}

It would be great to have this incorporated closer to your side, however. :grin: Thank you for any consideration!

Hi @DragonSpark,

It will be great if can reproduce the problem locally. Any steps? Do you have these exceptions using our demos?

I did try to run your demos locally but it appears they are on .NET5. I am waiting for RTM before jumping over. Perhaps this is the difference? I was able to reproduce this with a simple SLN here in netcoreapp3.1:

Radzen.Grid.zip (225.2 KB)

Note that the grid is in Index.razor and the exceptions should present themselves by simply launching the solution.

I've checked your project however I cannot reproduce any errors:

Ah, so to be sure, the errors are occurring in the Debug Output Window in Visual Studio:

Also, you should be able to see the error notification when pressing F5 in the browser. It might take a few times to see it, but it's there. :slight_smile:

I wanted to check in on this issue as I did not hear back. Were you able to reproduce it on your end? Please let me know if I can provide any additional/further information to help diagnose, if necessary. :+1:

I'm afraid that I'm unable to reproduce such exception:

Bummer @enchev. Actually, this particular issue might be rectified in .NET5, so maybe a non-issue there.

What about the exceptions thrown in the Debug Output Window in Visual Studio?

I have only Exception thrown: 'System.ObjectDisposedException' in Microsoft.AspNetCore.Components.dll and The thread 0xec0 has exited with code 0 (0x0) however I'm afraid that I don't know from where it comes from. The application stays operational.

OK so it sounds like the InvalidOperationException is handled more elegantly in .NET5 which is taking care of the toast notification as you have demonstrated.

However, if you CTRL-ALT-E in Visual Studio and catch on System.ObjectDisposedException you should see that RadzenGrid.RemoveColumn is in the stack trace.

I'll see if we can improve this somehow - at the moment I'm afraid that we cannot help much.

1 Like

Ah ok, I will continue to use my DataGrid<T> workaround until that time. Thank you for any consideration and/or efforts!