在asp.net核心控制器中,为啥ExecutionContext.SuppressFlow()会抛出“AsyncFlowControl对象必须在创建它的线程上使用”。

Posted

技术标签:

【中文标题】在asp.net核心控制器中,为啥ExecutionContext.SuppressFlow()会抛出“AsyncFlowControl对象必须在创建它的线程上使用”。【英文标题】:In asp.net core controller, why does ExecutionContext.SuppressFlow() throw "AsyncFlowControl object must be used on the thread where it was created."在asp.net核心控制器中,为什么ExecutionContext.SuppressFlow()会抛出“AsyncFlowControl对象必须在创建它的线程上使用”。 【发布时间】:2019-06-17 00:04:34 【问题描述】:

我试图抑制跨异步线程的执行上下文流。我已经写了下面的代码,但它会引发错误 -

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()

当我通过代码进行调试时,not 会抛出错误。只有在我不调试时才会出现。

示例代码:

[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!");

我是不是走错路了?

【问题讨论】:

执行使用await 设置的延续时,它可能位于与您的代码在await 之前所在的线程不同的线程上。 个人意见;不幸的是,这听起来像是 AsyncFlowControl 的一个非常糟糕的设计,因为它使用单词 Async 作为其名称的一部分并且不处理这种事情,听起来它更像是基于线程而不是异步(这是两个不同的东西)。 对我来说似乎很合理。一旦你在另一个线程上恢复,就为时已晚抑制执行上下文流。 【参考方案1】:

我正在尝试抑制跨异步线程的执行上下文流。

只需要问:为什么?

我已经写了下面的代码,但是它抛出了一个错误

当您在暂停它的不同线程上恢复执行上下文流时会发生此错误。

要修复此错误,请不要在 using 块中使用 await

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

通过使using 中的代码保持同步,您可以确保保持在同一个线程上。

【讨论】:

以上是关于在asp.net核心控制器中,为啥ExecutionContext.SuppressFlow()会抛出“AsyncFlowControl对象必须在创建它的线程上使用”。的主要内容,如果未能解决你的问题,请参考以下文章