c# - 如何调用保证同步的异步方法
问题描述
我有一个或多或少看起来像这样的方法:
public async Task PossiblyAsync(bool amIlucky)
{
if (amIlucky)
await Task.Delay(9000);
return;
}
在某些情况下,我确定不会在其中调用任何异步代码路径,但我仍然需要将所有事情都异步执行到最顶层。这本身不是问题,但我想知道当一个完美同步的代码假装是异步的时,它是否会引入一些不必要的开销,将所有结果包装在Task<T>
其中并做谁知道的其他事情。
另外,我真的希望它不要在线程之间跳转。我不确定它是否会发生,特别是因为 asp net core 中没有同步上下文。但是话又说回来,我不太明白同步上下文是什么:)
调用这种方法的最正确方法是什么?
解决方案
但我想知道当一个完美同步的代码假装是异步的时,它是否会引入一些不必要的开销,将所有结果包装在 Task 中并做其他人知道的事情。
它通常不会太糟糕。国家机器制造商试图针对这种情况进行优化,并避免一切不必要的事情——Task.CompletedTask
尽可能返回。但是,对于 return 的方法Task<T>
,这并不容易获得——您可能想要切换到ValueTask<T>
,因为这在“经常同步但需要返回值”的情况下更有效。在非常热的路径代码中(通常在 IO 库中),通常会在此处添加一个额外的层以完全避免状态机制,直到我们知道我们将要异步,但这是利基市场,可能超出了您的需要。
对于“避免状态机制”部分的示例(并再次强调大多数应用程序代码永远不需要这种级别的优化),请考虑:
ValueTask<Foo> SomeMethodAsync(...)
{
ValueTask<Bar> theThing = DoTheThingAsync(...); // some other things that we need
if (theThing.IsCompletedSuccessfully)
{
return new ValueTask<Foo>(ProcessResults(theThing.Result));
}
else
{
return Awaited(theThing);
}
static async ValueTask<Foo> Awaited(ValueTask<Bar> incomplete)
=> ProcessResults(await incomplete.ConfigureAwait(false));
static Foo ProcessResults(Bar bar) {...whatever...}
推荐阅读
- python - Discord bot python:discord.errors.ClientException:找不到ffmpeg
- angular - 具有异步的角度可观察数组未在退格上过滤
- tcp - vb6 tcp客户端/服务器winsock我从客户端到服务器的连接有问题
- html - Thymeleaf-如何在 th:each 循环内绑定 div 上的点击事件
- reactjs - 是否可以仅在道具更改时运行 useEffect 而不是状态更改?
- python - Python 中 Bash 的 exec $@ 等价于什么?
- c# - 拆分 PDF 并保存,但访问被拒绝
- java - 未命名空间的 r 类源
- python - 在单独的线程中运行 Panda3D
- shiny - 从 shinyapp.io 获取身份验证用户名