在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对象必须在创建它的线程上使用”。的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Asp.Net Core Kestrel 服务器向 Ngrok 返回 404 并且控制器永远不会被调用?
为啥此代码给我来自 Request.Form 的无效内容类型? (ASP.NET 核心)
为啥 Asp.net web api 控制器不从 IController 派生