.NET下Redis大幅性能提升之Batch异步批量读写
环境:
.NET CORE 3.1
redis nuget依赖:StackExchange.Redis
找了几篇博客文章,都是2018年前的,没有使用到async/await的异步操作,都是直接从task结果中Result取值。
在频繁的单机调试过程中遇到了阻塞问题,所以翻找资料,顺便把async/await搞懂
异步编程建议直接看微软官方的文章,一看就懂,看别人写的真是越看越懵
https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/async/
好了不废话,直接上redis batch的代码:
根据keys数组循环去redis读取hash数值,转成实体类,再存到List中
public async Task<List<T>> GetHashByKeyBatch<T>(string[] keys) { List<T> list = new List<T>(); List<Task<HashEntry[]>> valueList = new List<Task<HashEntry[]>>(); if (_db != null) { var batch = _db.CreateBatch(); foreach (var item in keys) { var hsObj = batch.HashGetAllAsync(item); valueList.Add(hsObj); } batch.Execute(); //使用WhenAny达成异步 while (valueList.Count > 0) { Task<HashEntry[]> hashEntry = await Task.WhenAny(valueList); var item = await hashEntry; var dic = item.ToDictionary(k => k.Name, v => v.Value); var model = JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(dic)); list.Add(model); valueList.Remove(hashEntry); } //用循环的话依然会阻塞,达不到异步的效果 //foreach (var hashEntry in valueList) //{ // var item = await hashEntry; // var dic = item.ToDictionary(k => k.Name, v => v.Value); // var model = JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(dic)); // list.Add(model); //} } return list.Count > 0 ? list : null; }
参考文章:
https://www.cnblogs.com/zhangtingzu/p/6939895.html
https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/async/
https://www.cnblogs.com/AlienXu/p/10609253.html