✅ Periodically (asynchronously) yielding in an otherwise synchronous method

I have a long-running CPU-bound algorithm that is being executed in a Blazor WASM application. I would like to cooperatively allow the UI to update / do event loop stuff etc.
Would you think this approach would work:
/*
we have garanteed async yields via the flag, so we should return the
task instead of synchronously waiting and thus force consumers to also
await. The intended consumer is of course calling our method from a single
threaded context like in Blazor WASM, allowing for periodic UI updates and
event loops to execute. Because we assume a single threaded context, even
calling ConfigureAwait(false) would not help, as even the thread pool only has
the single thread available.
see also: https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
*/
public static Task MyAlgoAsync() => MyAlgoCore(periodicallyYield: true);
/*
we can guarantee the task returned by MyAlgoCore to have already completed
because we disable all yields via the flag
*/
public static void MyAlgo() => MyAlgoCore(periodicallyYield: false).Wait();
private static async Task MyAlgoCore(bool periodicallyYield)
{
    //our algorithm takes a large number of steps
    for(var i = 0; i < 1000000; i++)
    {
        //we can put Task.Yield inbetween those steps
        if(periodicallyYield)
        {
            await Task.Yield();
        }
        //do some stuff
    }
}


Essentially we hide the await Task.Yield() path behind a flag, guarantueeing synchronous execution when desired, and enabling periodic yielding of the thread if not.

CCing @BenMcLean since we got to the idea together.
Was this page helpful?