0

I am attempting to suppress the flow of the execution context across asynchronous threads. I've written below code, but it throws an error -

InvalidOperationException: AsyncFlowControl object must be used on the thread where it was created.
System.Threading.AsyncFlowControl.Undo()
Web1.Controllers.ValuesController+<Get>d__0.MoveNext() in ValuesController.cs
+
                throw;
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

The error is not thrown when I debug through the code. It only occurs when I dont debug.

Sample code:

[HttpGet]
public async Task<IActionResult> Get()
{
    try
    {
        using (ExecutionContext.SuppressFlow())
        {
            await Switch.Instance.SwitchOn();
        }
    }
    catch (Exception ex)
    {
        var x = ex.Message;
        throw;
    }
    return Ok("Done!");
}

Am I going about it the wrong way?

perf-guru
  • 91
  • 3
  • 12
  • When the continuation that was set up using `await` is executed, it may be on a different thread than the thread your code was on before `await`. – Lasse V. Karlsen Jan 23 '19 at 12:05
  • 1
    Personal opinion; Unfortunately it sounds like a very broken design of `AsyncFlowControl`, given that it uses the word `Async` as part of its name and does not handle this kind of thing, it sounds like it is more thread-based than it is async (which are two different things). – Lasse V. Karlsen Jan 23 '19 at 12:06
  • Seems reasonable to me. Once you've resumed on another thread, it's too late to suppress flow of execution context. – Peter Ruderman Jan 24 '19 at 03:23

1 Answers1

4

I am attempting to suppress the flow of the execution context across asynchronous threads.

Just have to ask: Why?

I've written below code, but it throws an error

This errors happens when you restore execution context flow on a different thread that you suspended it on.

To fix this error, just don't use await within the using block:

Task task;
using (ExecutionContext.SuppressFlow())
  task = Switch.Instance.SwitchOn();
await task;

By keeping the code in the using synchronous, you are ensuring you stay on the same thread.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810