gpt4 book ai didi

c# - 为什么 C# 允许进行异步覆盖?

转载 作者:IT王子 更新时间:2023-10-29 04:12:44 24 4
gpt4 key购买 nike

在 C# 中,当您重写一个方法时,允许在原始方法不存在时使重写异步。这似乎是糟糕的形式。

让我疑惑的问题是:我是来协助解决负载测试问题的。大约 500 个并发用户时,登录过程将分解为重定向循环。 IIS 正在记录异常,消息为“异步模块或处理程序已完成,而异步操作仍在挂起”。一些搜索让我认为有人在滥用 async void,但我对源代码的快速搜索一无所获。

可悲的是,当我应该寻找更像 async\s*[^T] 的东西时,我正在搜索 async\s*void(正则表达式搜索) (假设 Task 不完全合格..你明白了)。

我后来发现是在基本 Controller 中的 async override void onActionExecuting。显然这一定是问题所在,而且确实如此。修复它(暂时使其同步)解决了问题。

但这给我留下了一个问题:当调用代码永远不会等待时,为什么您可以将覆盖标记为异步?

最佳答案

当基类(或接口(interface))声明了返回Task的虚方法时,只要返回Task就可以重写。 async 关键字只是提示编译器将您的方法转换为状态机。尽管编译器对您的方法施展魔法,但编译后的方法仍会返回一个任务


至于 void 虚拟方法,您可以覆盖一个没有 async 关键字(显然)并在其中启动一个非等待任务.当您使用 async 关键字覆盖它并在正文中使用 await 时,就会发生这种情况。调用者不会等待创建的任务(因为“原始”签名是 void)。两种情况都相似*:

public override void MyVirtualMethod()
{
// Will create a non awaited Task (explicitly)
Task.Factory.StartNew(()=> SomeTaskMethod());
}

public override async void MyVirtualMethod()
{
// Will create a non awaited Task (the caller cannot await void)
await SomeTaskMethod();
}

Stephen Cleary's article对此有一些注意事项:

  • 返回 Void 的异步方法有一个特定的目的:使异步事件处理程序成为可能。
  • 您应该更喜欢 async Task 而不是 async void。

*SomeTaskMethod 的实现、底层框架、SynchronizationContext 和其他因素可能并且将会导致上述每种方法产生不同的结果。

关于c# - 为什么 C# 允许进行异步覆盖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35817558/

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