我们假设我有以下代码:
IEnumerable<string> allKeys = _cache.Select(o => o.Key); Parallel.ForEach(allKeys,key => _cache.Remove(key));
如您所见,我正在检索_cache中的所有键,将它们存储在我的本地变量allKeys中,然后同时从_cache中删除所有键.
但是,我想要做一行.所以我想到的是:
Parallel.ForEach(_cache.Select(o => o.Key),key => _cache.Remove(key));
但是语句_cache.Select(o => o.Key)将在每次循环迭代时被调用,因此每次都检索不同数量的元素(因为我同时删除它们).
后一行代码是否安全?
_cache.Select(o => o.Key)在循环语句中,只调用一次,然后每次迭代使用原始结果,还是在每个迭代步骤中处理?
解决方法
As you can see,I’m retrieving all the keys in _cache,storing them in my local variable allKeys
不,你没有.由于称为延迟执行的内容,您存储的所有内容都是获取所有密钥的命令.您需要具体化此命令才能实际执行您认为的操作:
var allKeys = _cache.Select(o => o.Key).ToList();
那说:你的缓存线程安全吗?为什么它没有Clear方法?获取所有密钥并使用多线程删除它似乎是一个不那么好主意.
如果你坚持让它全部在一行,你可以使用PLINQ:
_cache.Select(o => o.Key).AsParallel().ForAll(key => _cache.Remove(key));
但同样:这似乎是一个坏主意.