Azure / azure-cosmos-dotnet-v3

.NET SDK for Azure Cosmos DB for the core SQL API
MIT License
723 stars 477 forks source link

Blazor WebAssembly Hangs When Initializing CosmosClient Due to Task.Run in SystemUsageMonitor #4551

Open Avenged opened 2 weeks ago

Avenged commented 2 weeks ago

Description

When using the Microsoft.Azure.Cosmos package in a Blazor WebAssembly project, the application hangs indefinitely upon initializing the CosmosClient. This issue is caused by the SystemUsageMonitor.CreateAndStart(recorders) method, which internally calls Task.Run to start a while loop. As WebAssembly does not support multithreading in the traditional sense, this results in the application freezing.

Expected Behavior

The Blazor WebAssembly application should function correctly while consuming the Microsoft.Azure.Cosmos library without hanging.

Actual Behavior

The Blazor WebAssembly application hangs indefinitely when initializing the CosmosClient.

Environment

Microsoft.Azure.Cosmos Version: 3.41.0 Blazor WebAssembly Version: both NET8.0 & NET9.0 Browser: Microsoft Edge Version 125.0.2535.92 Operating System: Windows 11

Steps to Reproduce

  1. Create a new Blazor WebAssembly project.

  2. Install the Microsoft.Azure.Cosmos package.

  3. Use the following code to reproduce the issue:

@page "/"
@using Azure.Core
@using Microsoft.Azure.Cosmos

<PageTitle>Home</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

@code {
    const string accountEndpoint = "...";
    const string accountKey = "...";
    const string databaseName = "...";

    protected override async Task OnInitializedAsync()
    {
        CosmosClient client = new(accountEndpoint, accountKey, new CosmosClientOptions
        {
            ConnectionMode = ConnectionMode.Gateway,
        });
        //At this point the issue should be happening
        var container = client.GetContainer(databaseName, "ApplicationDbContext");
        var scripts = container.Scripts;
        var response = await scripts.ExecuteStoredProcedureAsync<decimal>(
        "SomeProcedure",
        PartitionKey.None,
        Array.Empty<object>());
    }
}
  1. Run the application.

  2. Observe that the application hangs.

Logs and Error Messages

No specific error messages are shown; the application simply hangs.

Identified Issue

I identified that the issue occurs on the line 117 in DiagnosticsHandlerHelper.cs, which contains the following code:

this.systemUsageMonitor = SystemUsageMonitor.CreateAndStart(recorders);

The application functions correctly when this line is commented out, indicating that the problem lies with the use of Task.Run within WebAssembly.

Temporary Workaround

Commenting out line 117 in DiagnosticsHandlerHelper.cs, which contains the following code:

this.systemUsageMonitor = SystemUsageMonitor.CreateAndStart(recorders);

Possible Solution

Consider replacing the Task.Run with a timer-based approach or another asynchronous pattern that is compatible with WebAssembly.

Thank you for your attention to this matter. Please let me know if any further information is required.