【发布时间】:2023-03-28 15:46:01
【问题描述】:
我在线程环境中运行时遇到了一些 redis 问题。
我有一个名为 AwaitableParallelForeachWorker 的类,我可以在其中为有效负载中的每个项目运行特定的函数。 (我知道它不漂亮,但它确实有效)
public class AwaitableParallelForeachWorker : IAwaitableParallelForeachWorker
{
private readonly object _lockObject = new object();
private int _tasksCompleted;
public async Task Run<T>(Func<T, Task> action, IEnumerable<T> payload)
{
var list = payload.ToList();
var tasks = list.Select(x => new Task(async () =>
{
await action(x);
TaskDone();
}));
Parallel.ForEach(tasks, task => task.Start());
while (_tasksCompleted < list.Count)
{
await Task.Delay(10);
}
}
public void TaskDone()
{
lock (_lockObject)
{
_tasksCompleted++;
}
}
}
这里是redis缓存代码:
public class NewsappRedisCache : INewsappRedisCache
{
private static readonly string ConnectionString = ConfigurationManager.AppSettings["RedisCache"];
private static readonly Lazy<ConnectionMultiplexer> LazyConnection =
new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(ConnectionString));
private static IDatabase MimerArticleDatabase => Connection.GetDatabase(2);
public async Task<MimerArticle> GetMimerArticleAsync(Guid id)
{
var redisValue = await MimerArticleDatabase.StringGetAsync($"{nameof(MimerArticle)}-{id}");
if (!redisValue.HasValue) return null;
var mimerArticle = JsonConvert.DeserializeObject<MimerArticle>(redisValue.ToString());
return mimerArticle;
}
我编写了这个简单的测试,它使用 AwaitableParallelForeachWorker 调用我的 redis 缓存 1000 次
public class Test
{
private NewsappRedisCache _redisCache;
[Fact]
public async void TestRedis()
{
var guids = new List<Guid>();
for (var i = 0; i < 1000; i++)
{
guids.Add(Guid.NewGuid());
}
_redisCache = new NewsappRedisCache();
await new AwaitableParallelForeachWorker().Run(CallRedis, guids);
}
private async Task CallRedis(Guid id)
{
await _redisCache.GetMimerArticleAsync(id);
}
}
现在变得很奇怪。有时 1000 次访问 redis 缓存会在一瞬间执行。我已经通过检查 azure 门户验证了 get 确实命中了缓存。但有时每次获取大约需要 1 秒。
我不知道为什么。我尝试更改 AwaitableParallelForeachWorker 的功能,但它一直不一致。 如果我在正常的 foreach 中运行每个 get,它执行得很好,但不如 AwaitableParallelForeachWorker 实际工作时那么快。
所以我一直认为它与线程/任务有关。
谁能提供一些帮助?
【问题讨论】:
标签: c# multithreading azure redis