Search code examples
c#asynchronousasync-await

What should be in the end of await-async chain with busy wait/CPU bound code?


Let's say I have this sample code

var t = Float();
...
t.Wait();


async Task Float()
{
    while (LoopIsAllowed)
    {
        TryToComplete();
        System.Threading.Thread.Sleep(500);
    }
}

In this case code run synchronously and I have warning "async method lacks 'await'". I really need to run Float() async so this warning should almost always be considered. As I see it the problem here is that if I call Float() and await it latter the application will not work as intended and it will stuck on var t = Float() instead of t.Wait()

But I do not see any way to fix that other than like this:

async Task Float()
{
    while (LoopIsAllowed)
    {
        TryToComplete();
        await Task.Run(() => System.Threading.Thread.Sleep(500));
    }
}

Does this fix have any sense? In terms of memory and processor resources is it fine to call Task.Run or is there better way? As I see it after the fix calling var t = Float() will force the code to run synchronously until await Task.Run is reached. Then parent code will continue execution until t.Wait(). Only then it will continue to iterate through while (LoopIsAllowed) loop. And this behavior is exactly what I need.

Is this correct?

EDIT: What should I do if I do not have any delay in my code at all? And there is no other place to await. Should I just add delay? Or should I analyze code and add Task.Run somewhere around time consuming calculations blocks?


Solution

  • Never use Thread.Sleep in async method.

    use await Task.Delay(); instead of Thread.Sleep

    async Task Float()
    {
        while (LoopIsAllowed)
        {
            TryToComplete();
            await Task.Delay(500);
        }
    }
    

    and in main method use GetAwaiter().GetResult() instead of wait

    var t = Float().GetAwaiter().GetResult();