gpt4 book ai didi

c# - 调用异步 ActionResults 时,AllowVoidAsyncOperations 何时设置?

转载 作者:行者123 更新时间:2023-12-03 12:49:30 25 4
gpt4 key购买 nike

更新

经过一番思考,我得出的结论是,我可能没有提出正确的问题。

给出以下代码:

public class HomeController : Controller
{
public Task<string> DownloadAsync(string url)
{
using (var web = new WebClient())
{
return web.DownloadStringTaskAsync(url);
}
}

// THROWS EXCEPTION
public ActionResult Index()
{
var data = DownloadAsync("http://google.dk");
return Content(data.Result);
}

// WORKS
public async Task<ActionResult> IndexWorks()
{
var data = await DownloadAsync("http://google.dk");
return Content(data);
}
}

很明显(尤其是在阅读@Stephen Cleary 的博客文章之后),ActionResult Index()代码会导致死锁。但为什么呢?

经过一番挖掘,我发现 .NET 4.5推出新的AspNetSynchronizationContext ,这应该更加“任务友好”。下载.NET 4.5的源代码看看新的AspNetSynchronizationContext内部,我认为调用 OperationStarted ,将导致检查名为 AllowVoidAsyncOperations 的 bool 值。如果该值为 true,则没有问题。然而,如果这个 bool 值的值为 false,它将抛出以下异常:

An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async=\"true\" %>.

经过深思熟虑,我想通了,调用 async Task<ActionResult> IndexWorks()以某种方式设置 AllowVoidAsyncOperations为真。 - 调用同步版本时,它保持默认值:false。

因此我的问题是:

异步ActionResult什么时候调用AspNetSynchrnoizationContext的内部方法,即设置 AllowVoidAsyncOperations为真? - 到目前为止,我已将范围缩小到类 CallHandlerExecutionStep里面HttpApplication类(class)。 - 但是,我不确定它如何决定是否允许。

最佳答案

如果您尝试在请求生命周期中不允许的点(或完全在请求上下文之外)执行异步操作,则 ASP.NET 会引发此特定异常。

您不应该在 ASP.NET MVC 中看到这一点。有两件事需要检查:

  1. 确保您在 .NET 4.5 上运行。我怀疑您已经是这样了,否则您根本不会看到该消息。
  2. 确保您有 UseTaskFriendlySynchronizationContext set to true or have httpRuntime.targetFramework set to 4.5 .

更新:经过反射(reflection),在 ASP.NET MVC 中还有另外两种情况可能导致此问题:

  1. 确保您没有调用任何 async void 方法。
  2. 确保您没有使用 EAP 组件。例如:
    1. HttpClientTAP ,所以它会起作用。
    2. HttpWebRequestAPM ,所以围绕它的 TAP 包装器就可以工作。
    3. WebClientEAP ,所以会导致这个错误。无论您使用 DownloadStringAsync 还是 DownloadStringTaskAsync,都是如此。

关于c# - 调用异步 ActionResults 时,AllowVoidAsyncOperations 何时设置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17013536/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com