Warm tip: This article is reproduced from serverfault.com, please click

How to make a Blazor page mutex

发布于 2021-10-20 21:02:02

I want to make it so one page of my Blazor app can function only once at the same time. Meaning when any user starts its functionality (it's working on our database) another won't be able to until all the work is finished, first.

Kind of like locking / using a mutex.

Questioner
Tessaract
Viewed
0
Bennyboy1973 2021-10-21 07:08:48

For shared state information, it's normal in Blazor to add a Singleton with Dependency Injection. Warning this is not tested code, but you can get the idea.

Create a Singleton class:

public class LockState {
     public string UserId { get; set; }
}

Register it in Startup.cs

public void ConfigureServices(IServiceCollection services){
    // . . .
    services.AddSingleton<LockState>();
}

Inject it into PageToLock.razor

@inject LockState LS
@inject AuthenticationStateProvider ASP

@if(LS.UserId == this.Userid){
    <YourDataBaseControl />
    <button @onclick="()=> this.UserId = null">X</button>
}
else {
    <div>The Database Control is Currently being used. . . </div>
}

@code {
    string UserId;
    protected override async Task OnInitializedAsync(){
        UserId = (await ASP.GetAuthenticationStateAsync()).User.FindFirst(c => c.Type.Contains("nameidentifier"))?.Value;
        if (LS.UserId is null) LS.UserId = this.UserId;
    }
}

Note that there's a problem. When the user is done with the page, they have to set LS.UserId to null or it will be locked for all eternity. If they forget and just close the browser. . . that will be bad. You'll have to figure out a reliable way to guarantee that the lock is removed. You can add Timers to check if the circuit is still open, and should probably have an event so PageToLock.razor knows when the lock is removed.