Home > OS >  Is there a way to force a context switch without Task.Delay in async code
Is there a way to force a context switch without Task.Delay in async code

Time:10-27

I have code with looks something like:

I was trying to avoid putting it in a Task.Run because it is async and should run fine on the main thread

However it does not do a context switch (and will run forever), unless I insert a Task.Delay into the loop

Is there a better way of achieving this (Without Task.Run)?

var tasks = new List<Task>();
var cts = new CancellationTokenSource();
tasks.Add(DoSomething(cts.Token));
cts.Cancel();
Task.WaitAll(tasks.ToArray());
Console.WriteLine("Done");

async Task DoSomething(CancellationToken ct)
{
    while (!ct.IsCancellationRequested)
    {
        await Task.CompletedTask;
        await Task.Delay(1); // Without this is doesn't do context switch
    }
}

I'm trying to unit test cancellation when I have a heavy workload an encountered this problem.

CodePudding user response:

Try

async Task DoSomething(CancellationToken ct)
{
    while (!ct.IsCancellationRequested)
    {
        //await Task.CompletedTask; //you can omit this line
        await Task.Yield();
    }
}

CodePudding user response:

If you want to simulate a cancelable operation, the simplest way is probably this:

Task DoSomething(CancellationToken cancellationToken)
{
    return Task.Delay(Timeout.Infinite, cancellationToken);
}

The cancellationToken parameter has canceling semantics, meaning that when the token is canceled, the Task will transition to the Canceled state. If you want it to have stopping semantics, which is the non standard semantics for a CancellationToken, you could do this:

async Task DoSomething(CancellationToken stoppingToken)
{
    try { await Task.Delay(Timeout.Infinite, stoppingToken); }
    catch (OperationCanceledException) { }
}

Now when the token is canceled, the Task will transition to the RanToCompletion state. Be aware that it's extremely rare to see a CancellationToken parameter with stopping semantics in the standard .NET libraries.

  • Related