Home > Mobile >  Why method with an await Task.Delay inside an if statement is not working in C#?
Why method with an await Task.Delay inside an if statement is not working in C#?

Time:11-28

I'm sorry if the tittle is a bit confusing.

I have an array-sorting webapp in Blazor.

This is the important piece of code:

<MudButton OnClick="Sort" Disabled="Sorting" Variant="Variant.Outlined" >Sort</MudButton>
<MudButton OnClick="Accelerate" Disabled="@(!Sorting)" Variant="Variant.Outlined">Finish</MudButton>

@code{
    public bool Sorting { get; set; } = false;
    public bool Accelerating { get; set; } = default!;

    public void Sort()
    {
        Sorting = true;
        Bubble();
    }

    public void Accelerate()
    {
        Accelerating = true;
    }


    public async void Bubble()
    {
        while (!IsSorted(List))
        {
        //algorithm
            StateHasChanged();
            if (!Accelerating)
            {
                await Task.Delay((Speed - MAX_SPEED) * -1 == 0 ? 1 : (Speed - MAX_SPEED) * -1);
            }
        }
        Sorting = false;
        Accelerating = false;
        StateHasChanged();
    }
}

The sorting part works just fine. When I click the Accelerate button the await Task.Delay should be skipped. But when I do, the whole application freezes like this:

enter image description here

enter image description here

It won't respond. Nothing in console.

Where is the problem? Thanks

CodePudding user response:

I'm guessing that when Accelerating becomes true, your CPU usage skyrockets.

Awaiting the delay gives the UI a chance to respond to user input, but without it, it can't. Once Accelerating becomes true, you end up in an infinite loop that occupies the UI thread entirely, and all user input gets put in a queue waiting for the UI thread to be freed, which never happens.

CodePudding user response:

The line

Accelerating = false;

Will flip Accelerating to false the 2nd time you click the button, thus opening things up for Task.Delay to run.

CodePudding user response:

The problem was the 'StateHasChanged()' It should have been inside the if.

CodePudding user response:

I think your problem is "method without an await Task.Delay inside an if statement is not working".

As noted by others you are tying up the single Wasm thread. Your app should become responsive again when the sorting is done though.

// algorithm ...

//StateHasChanged();
if (!Accelerating)
{
    StateHasChanged();
    await Task.Delay((Speed - MAX_SPEED) * -1 == 0 ? 1 : (Speed - MAX_SPEED) * -1);
}
else
{
    await Task.Delay(1);
}

The use of async void is dubious but probably intentional here. I would change it to:


public async Task Sort()
{
    Sorting = true;
    await Bubble();
    Sorting = false;
}

public async Task Bubble()
{
   ... as before but without Sorting
}
  • Related