【问题标题】:Redis cache InvalidOperationException: Reading is not allowed after reader was completedRedis缓存InvalidOperationException:读取完成后不允许读取
【发布时间】:2021-01-29 13:46:44
【问题描述】:

我有一个网络作业不断将数据插入 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 提出了同样的问题。

nuget 版本详细信息 -

错误堆栈 - 内部异常 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()

【问题讨论】:

  • 您使用的 StackExchange.Redis nuget 版本是什么?另请分享完整的堆栈跟踪。
  • 使用 nuget 详细信息更新问题,请检查谢谢

标签: c# azure c#-4.0 redis stackexchange.redis


【解决方案1】:

我在代码中发现了几个问题:

  1. 您应该重复使用相同的 redis 客户端实例,以避免与 redis 服务器的 tcp 连接过多。
  2. 不要使用.Result 以避免阻塞当前线程。将方法更新为异步并在 GetAsync 上使用 await。
  3. 确保不要在缓存条目中存储大对象(在这种情况下,List&lt;MyObject&gt; 不应是大列表)

以下是更新后的代码:

        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);
        }

【讨论】:

  • 感谢我尝试使用相同但相同的错误 :( 使用 cosmos db 而不是 redis 缓存来存储和检索数据更好吗?
  • 取决于什么样的数据。如果它必须持久化,那么 redis 不是正确的选择。如果是用于(临时)缓存,那么 redis 更适合。
  • 它是我从 9 点到 3 点从 webjob 连续收集的股票市场数据。并使用另一个函数读取最新的 5 分钟数据,这是我的用例
  • 问题是您是只处理最近的数据还是想长期维护它。此外,Redis v/s CosmosDB 的问题是一个架构问题,StackOverflow 不是正确的论坛stackoverflow.com/help/asking
猜你喜欢
  • 2013-07-26
  • 1970-01-01
  • 2020-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-04
  • 2019-01-14
  • 1970-01-01
相关资源
最近更新 更多