ASP.NET Core MemoryCache异步和等待的GetOrCreateAsync开销

问题描述 投票:-1回答:1

首先是一点背景:

目前,我们正在使用ASP.NET Core MemoryCache MemoryCache Doc

IMemoryCache界面上有一个名为GetOrCreateAsync(...)的方法,我可以在其中传递工厂函数Func<ICacheEntry, Task<TItem>> factory

由于这是一个异步方法签名,我必须一直实现async await(有时是大约8个方法的callstack),即使缓存命中本身是同步的。在我的场景中,我按每个请求大约200-2500次点击缓存。有些参赛作品我每隔60分钟就会刷新一次。

现在的问题是:

我目前的理解是,.NET Core必须为每个调用创建一个状态机,即使我只是以同步的方式命中缓存,因为它的方法签名。你们其中一个人知道这有多大的开销吗?是否更有意义创建一个同步工厂(这是一个Web-API调用),有一点阻塞,以便我可以使用GetOrCreate(...)?或许你们中的一些人有完全不同的想法。

希望你能得到我的痛点。

c# asynchronous asp.net-core async-await
1个回答
-1
投票

你在这里有很多困惑。首先也是最重要的是,委托不是异步委托,而是返回任务的委托。通常将两者混为一谈,因为您通常只从异步操作返回任务,但您不必这样做。为了满足代表,您只需要使用Task.FromResult(foo),其中foo是您最终返回的任何内容。重要的是,可以同步满足该返回,因此,如果基础进程是同步的,则无需从此处依赖async / await。

其次,await默认会创建一个SynchronizationContext。这在线程切换的情况下存在,因为任何线程本地需要移动到新线程以防止丢失引用。这涉及到向堆中添加内容,是的,可能会降低性能。但是,如果您没有使用线程本地和/或没有线程切换的可能性,则不需要这样做。在这种情况下,您可以在异步方法上调用ConfigureAwait(false)。特别是ASP.NET Core根本不使用线程局部化(通过依赖注入来满足交叉依赖性)。因此,使用ConfigureAwait(false)始终是安全的,您应该将其添加到您执行的每个异步操作中。在这种特殊情况下,SynchronizationContext是无用的,因为你的操作是同步的,这意味着无论如何都不会发生线程切换。

© www.soinside.com 2019 - 2024. All rights reserved.