Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.GetAwaiter().GetResult() limitation in Blazor WebAssembly #57429

Closed
1 task done
winscripter opened this issue Aug 20, 2024 · 1 comment
Closed
1 task done

.GetAwaiter().GetResult() limitation in Blazor WebAssembly #57429

winscripter opened this issue Aug 20, 2024 · 1 comment
Labels
area-blazor Includes: Blazor, Razor Components ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. Status: Resolved

Comments

@winscripter
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

Hi,

Blazor WebAssembly seems to have some issues with the Task.GetAwaiter().GetResult() method. This method is typically used when we want to run an asynchronous task without the need of awaiting it. This results in asynchronous code running synchronously.

However, when we try to use Task.GetAwaiter().GetResult() in Blazor WebAssembly, like in this code:

using System.Threading.Tasks;

static void SomeSynchronousMethod()
{
    Task.Run(() =>
    {
    })
    .GetAwaiter() /*<---*/
    .GetResult(); /*<---*/
    // Notice that Task.Run() is an async method but we don't use 'await'
}

we get an exception in the JS console:

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Cannot wait on monitors on this runtime.
System.PlatformNotSupportedException: Cannot wait on monitors on this runtime.
   at System.Threading.Monitor.ObjWait(Int32 millisecondsTimeout, Object obj)
   at System.Threading.Monitor.Wait(Object obj, Int32 millisecondsTimeout)
   at System.Threading.ManualResetEventSlim.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.SpinThenBlockingWait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.InternalWaitCore(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.InternalWait(Int32 millisecondsTimeout, CancellationToken cancellationToken)

While code in Task.Run(...) does seem to run, .GetAwaiter().GetResult() does result in an exception.

Expected Behavior

The expected behavior when we use .GetAwaiter().GetResult() is that the asynchronous code should run, albeit it might cause the page to hang for a bit depending on the amount of time it takes for that asynchronous code to complete (just like in Blazor Server or ASP.NETCore, or in desktop apps like Windows Forms or WPF).

Steps To Reproduce

Here is a simple, minimal code to reproduce the issue. Create a new Razor Component and paste this code:

@using System.Threading.Tasks

<p>After clicking the button below, the exception should be logged in the JS console.</p>
<button @onclick="Reproduce">Click to reproduce the issue</button>

@code {
    public void Reproduce()
    {
        Task.Run(() =>
        {
        })
        .GetAwaiter()
        .GetResult();
    }
}

BlazorFiddle

Exceptions (if any)

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Cannot wait on monitors on this runtime.
System.PlatformNotSupportedException: Cannot wait on monitors on this runtime.
   at System.Threading.Monitor.ObjWait(Int32 millisecondsTimeout, Object obj)
   at System.Threading.Monitor.Wait(Object obj, Int32 millisecondsTimeout)
   at System.Threading.ManualResetEventSlim.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.SpinThenBlockingWait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.InternalWaitCore(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.InternalWait(Int32 millisecondsTimeout, CancellationToken cancellationToken)

.NET Version

8.0.303

Anything else?

ASP.NETCore version: 8.0

IDE: I use both Visual Studio 2022 17.10.5 and VSCode, the issue persists.

dotnet --info result (I had to translate some text):

.NET SDK:
 Version:           8.0.303
 Commit:            29ab8e3268
 Workload version:  8.0.300-manifests.34944930
 MSBuild version:   17.10.4+10fbfbf2e

Operating system:
 OS Name:     Windows
 OS Version:  10.0.22631
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\8.0.303\

Installed .NET workloads:
 [aspire]
   Installation source: VS 17.10.35122.118
   Manifest version:    8.0.0/8.0.100
   Manifest path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.0.0\WorkloadManifest.json
   Installation type:        FileBased


Host:
  Version:      8.0.7
  Architecture: x64
  Commit:       2aade6beb0

.NET SDKs installed:
  6.0.418 [C:\Program Files\dotnet\sdk]
  8.0.303 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]
    registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-blazor Includes: Blazor, Razor Components label Aug 20, 2024
@MackinnonBuck
Copy link
Member

Thanks for reaching out.

This doesn't work because the WebAssembly runtime is single-threaded. There's an ongoing effort to add multithreading support. See dotnet/runtime#68162.

@MackinnonBuck MackinnonBuck closed this as not planned Won't fix, can't repro, duplicate, stale Aug 20, 2024
@MackinnonBuck MackinnonBuck added the ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. label Aug 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. Status: Resolved
Projects
None yet
Development

No branches or pull requests

2 participants