c# - Redis缓存InvalidOperationException:读取完成后不允许读取
问题描述
我有一个不断将数据插入redis的网络作业我有另一个时间触发功能,可以在每5分钟后从同一个redis缓存中读取数据。
public static void ProcessData([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer)
{
var newCacheclient = new RedisCacheClient(Program.spRedisCacheConnectionPoolMgr, Program.serializer, Program.redisConfiguration).Db0;
var cachedData = newCacheclient.GetAsync<List<MyObject>>("mydata").Result;
执行 10-15 分钟后,时间触发功能出现错误。有人知道如何解决这个问题吗?
InvalidOperationException:阅读器完成后不允许阅读。
我也向 github 提出了同样的问题。
错误堆栈 - 内部异常 1:
InvalidOperationException: Reading is not allowed after reader was completed.
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at MyData.Functions.ExecuteTrade(TimerInfo myTimer) in C:\Users\\Functions.cs:line 27
at Microsoft.Azure.WebJobs.Host.Executors.VoidMethodInvoker`1.InvokeAsync(TReflected instance, Object[] arguments)
at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`1.<InvokeAsync>d__0.MoveNext()
at System.IO.Pipelines.ThrowHelper.ThrowInvalidOperationException_NoReadingAllowed()
at System.IO.Pipelines.Pipe.AdvanceReader(SequencePosition& consumed, SequencePosition& examined)
at System.IO.Pipelines.Pipe.DefaultPipeReader.AdvanceTo(SequencePosition consumed, SequencePosition examined)
at StackExchange.Redis.PhysicalConnection.<ReadFromPipe>d__110.MoveNext() in /_/src/StackExchange.Redis/PhysicalConnection.cs:line 1495
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at StackExchange.Redis.Extensions.Core.Implementations.RedisDatabase.<GetAsync>d__14`1.MoveNext()
解决方案
我在代码中看到了几个问题:
- 您应该重复使用相同的 redis 客户端实例,以避免与 redis 服务器的 tcp 连接过多。
- 不要使用
.Result
以避免阻塞当前线程。将方法更新为异步并在 GetAsync 上使用 await。 - 确保不要在缓存条目中存储大对象(在这种情况下
List<MyObject>
不应该是大列表)
以下是更新后的代码:
private static readonly IRedisCacheClient redisCacheClient = new RedisCacheClient(Program.spRedisCacheConnectionPoolMgr, Program.serializer, Program.redisConfiguration);
public static async Task ProcessData([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer)
{
var redisDB = redisCacheClient.Db0;
var cachedData = await redisDB.GetAsync<List<MyObject>>("mydata").ConfigureAwait(false);
}
推荐阅读
- c++ - 找到 $number 然后用 $number+1 替换它?
- python - 如何删除 sys.path.append("../") 但没有得到 ImportError: No module named XXX
- javascript - 如何使用 vue js 在谷歌地图中放置标记?
- android - 升级到 Kotlin 1.2.60、Android Studio 3.1.3 时出错
- angular - Angular 5中的Constructor和ngOnInit有什么区别
- google-chrome - Silverlight -- 使用 chrome 打开网页
- c# - 如果我指定参数而不是使用配置文件,ServiceHost 的地址是什么
- openstreetmap - graphhopper 自定义 osm.pbf 文件
- java - 从 Android 中录制的音频中去除嗡嗡声
- python - 将列表写入 CSV un Python