我正在Blazor Server(.NET 6(上开发一个应用程序。这种异常情况发生了很多次。但是,无论页面是否多次渲染,每个页面中都会出现这种异常。例如,在登录页面中(不需要渲染多次(会出现此异常。我检查了每个事件订阅,当处理发生时,所有事件都取消订阅(所以我认为事件订阅不是问题(。我想以我的代码为例,但它有超过5万行,你不想阅读所有的代码。
我注意到该应用程序有点慢,可能会由一些任务或线程运行。如果是问题,我该怎么办?
我读到这个异常发生在一个任务多次结束时,我认为情况并非如此。
如果StateHasChanged
方法抛出这个异常,我在代码中有许多InvokeAsync(StateHasChanged).Wait()
和await InvokeAsync(StateHasChanged)
。没有这些,但有一些。
我试了什么?我尝试删除所有可能的异步方法(删除await
并使用.Result
(。此外,当处置所有Callback += Method
时,Callback -= Method
被取消订阅。应用程序性能非常好,使用了不到所有可用内核的3%。
Error: System.InvalidOperationException: An attempt was made to transition a task to a final state when it had already completed.
at System.Threading.Tasks.TaskCompletionSource`1.SetException(Exception exception)
at Microsoft.JSInterop.Infrastructure.TaskGenericsUtil.TcsResultSetter`1.SetException(Object tcs, Exception exception)
at Microsoft.JSInterop.Infrastructure.TaskGenericsUtil.SetTaskCompletionSourceException(Object taskCompletionSource, Exception exception)
at Microsoft.JSInterop.JSRuntime.EndInvokeJS(Int64 taskId, Boolean succeeded, Utf8JsonReader& jsonReader)
at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.EndInvokeJS(JSRuntime jsRuntime, String arguments)
at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.<>c.<InvokeAsync>b__8_0(Object state)
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost.EndInvokeJSFromDotNet(Int64 asyncCall, Boolean succeeded, String arguments)
此异常不会破坏应用程序。仅出现在控制台中并显示典型的";发生了未经处理的异常。有关详细信息,请参阅浏览器开发工具">
看起来您的异步代码太复杂了。我的猜测是:
- 您使用的是
TaskCompletionSource
,并在它已设置为完成时将其设置为完成 - 对已完成的任务执行一些JsInterop调用
我所说的复杂是指:
InvokeAsync(StateHasChanged).Wait()
为什么选择.Wait()
?而不是:
await InvokeAsync(StateHasChanged);
这很难说,因为没有代码。