0

When i execute many task blazor ui freezes until all the tasks are completed. I dont know how to limit for example the number of task or somehing in blazor to keep showing ui eventhough tasks keeps running in background. I think this problem is more a asyncrhonous rather than blazor.

Heres my scenario: I have a simple class,

    public class Demo
    {
        public int Id;
        public bool WorkDone { get; set; }

        public Demo(int id)
        {
            this.WorkDone = false;
            this.Id = id;
        }


        //some async job that takes time

        public async Task Work()
        {
            await Task.Run(async () =>
            {
                Random r = new();

                Thread.Sleep(1000 * r.Next(1, 10));
                this.WorkDone = true;

            });

        }
    }

So my main objective is to show a list of this demo objects, but this list has to be updated with respective object values when the values area updated. So i did a simple table to show object values, and after the job is done i called statehaschanged async to forze to update the ui:

@page "/"

<button @onclick=DoWork>Do Work</button>
<table>
    <tr>
        <th>id</th>
        <th>state</th>
    </tr>
    @foreach(var item in this.data)
    {
        <tr>
            <td>@item.Id</td>
            <td>@item.WorkDone</td>
        </tr>
    }
</table>

@if (allworkdone)
{
    <div class="alert alert-success fade-in" role="alert">
        Work Done!
    </div>
}

@code {
    int max = 10;
    List<Demo> data= new();
    bool allworkdone = false;

    protected override void OnInitialized()
    {
        foreach (var item in Enumerable.Range(0, max))
        {
            this.data.Add(new Demo(item));
        }
    }
    
    public void DoWork()
    {
        List<Task> tasks = new ();  
        data.AsParallel().ForAll(async x=>
        {
            await x.Work();
            await InvokeAsync(StateHasChanged);
        });
        allworkdone = true;
        StateHasChanged();
    }

So far so good , but when i add more task( change max to 10000 for example), the ui locks and shows the following:

UI locks

I think the cause is that all "threads" are consumed so the ui cant be refreshed till all the job is done. Because after the job is done, the ui "comes back"

What are the ways to prevent this effect? Working on blazor server, net6. Thanks!

hesolar
  • 543
  • 4
  • 23
  • Update: I try also with  data.AsParallel().WithDegreeOfParallelism, but i get the same result – hesolar Jan 03 '23 at 11:19
  • https://stackoverflow.com/questions/11564506/nesting-await-in-parallel-foreach From what I understand, Parallel does not work with async/await – maciek Jan 03 '23 at 12:24
  • 1
    Dont use Thread.Sleep(...). Use instead await Task.Delay(...) this allows other task to continue in parallel – user3529134 Jan 03 '23 at 17:01
  • 1
    Try to use await Parallel.ForEachAsync(data, new ParallelOptions { MaxDegreeOfParallelism = 3 }, async (item, token) => { //handle item} – user3529134 Jan 03 '23 at 17:18

0 Answers0