首页 问答 .NET HybridCache 缓存到内存时怎么也会进行序列化
问题详情

最近在 ASP.NET Core 10 项目中遇到的问题,出现问题的 C# 代码如下:

var cacheOptions = new HybridCacheEntryOptions
{
    LocalCacheExpiration = TimeSpan.FromMinutes(1),
    Flags = HybridCacheEntryFlags.DisableDistributedCache
};
return await hybridCache.GetOrCreateAsync(
    cacheKey,
    async token => await GetRuleListByCheckee<TCheckee>(),
    cacheOptions);

因为序列化失败,才发现 HybridCache 在使用内存缓存(in-memory cache)也进行了序列化操作

MessagePack.MessagePackSerializationException: Failed to serialize ...
 ---> MessagePack.FormatterNotRegisteredException: ...
   at MessagePack.FormatterResolverExtensions.Throw(Type t, IFormatterResolver resolver)
   at MessagePack.Formatters.ListFormatter`1.Serialize(MessagePackWriter& writer, List`1 value, MessagePackSerializerOptions options)
   at MessagePack.MessagePackSerializer.Serialize[T](MessagePackWriter& writer, T value, MessagePackSerializerOptions options)
   --- End of inner exception stack trace ---
   at MessagePack.MessagePackSerializer.Serialize[T](MessagePackWriter& writer, T value, MessagePackSerializerOptions options)
   at MessagePack.MessagePackSerializer.Serialize[T](IBufferWriter`1 writer, T value, MessagePackSerializerOptions options, CancellationToken cancellationToken)
   at Cnblogs.Cache.Hybrid.Extensions.HybridCacheMessagePackSerializer`1.Serialize(T value, IBufferWriter`1 target)
   at Microsoft.Extensions.Caching.Hybrid.Internal.DefaultHybridCache.TrySerialize[T](T value, BufferChunk& buffer, IHybridCacheSerializer`1& serializer)
   at Microsoft.Extensions.Caching.Hybrid.Internal.DefaultHybridCache.StampedeState`2.BackgroundFetchAsync()
   at Microsoft.Extensions.Caching.Hybrid.Internal.DefaultHybridCache.StampedeState`2.<UnwrapReservedAsync>g__AwaitedAsync|18_0(ILogger log, Task`1 task)

如何让 HybridCache 不进行这个序列化操作?

回答

通过 HybridCache 的开源代码 DefaultHybridCache.StampedeStateT.cs#L330 知道了,满足以下条件才不进行序列化


// If we're writing this value *anywhere*, we're going to need to serialize; this is obvious
// in the case of L2, but we also need it for L1, because MemoryCache might be enforcing
// SizeLimit (we can't know - it is an abstraction), and for *that* we need to know the item size.
// Likewise, if we're writing to a MutableCacheItem, we'll be serializing *anyway* for the payload.
//
// Rephrasing that: the only scenario in which we *do not* need to serialize is if:
// - it is an ImmutableCacheItem (so we don't need bytes for the CacheItem, L1)
// - we're not writing to L2
CacheItem cacheItem = CacheItem;
bool skipSerialize = cacheItem is ImmutableCacheItem<T> && (activeFlags & FlagsDisableL1AndL2Write) == FlagsDisableL1AndL2Write;

版权:言论仅代表个人观点,不代表官方立场。转载请注明出处:https://www.stntk.com/question/2716.html

发表评论
暂无评论

还没有评论呢,快来抢沙发~

点击联系客服

在线时间:8:00-16:00

客服QQ

70068002

客服电话

400-888-8888

客服邮箱

70068002@qq.com

扫描二维码

关注微信公众号

扫描二维码

手机访问本站