c# – 此MSDN上的Lazy目的示例
作者:互联网
我一直在读这个Asynchronous article from MSDN,但我无法理解Lazy< T>的目的了.在给定的例子上.
public class AsyncCache<TKey, TValue>
{
private readonly Func<TKey, Task<TValue>> _valueFactory;
private readonly ConcurrentDictionary<TKey, Lazy<Task<TValue>>> _map;
public AsyncCache(Func<TKey, Task<TValue>> valueFactory)
{
if (valueFactory == null) throw new ArgumentNullException("loader");
_valueFactory = valueFactory;
_map = new ConcurrentDictionary<TKey, Lazy<Task<TValue>>>();
}
public Task<TValue> this[TKey key]
{
get
{
if (key == null) throw new ArgumentNullException("key");
return _map.GetOrAdd(key, toAdd =>
new Lazy<Task<TValue>>(() => _valueFactory(toAdd))).Value;
}
}
}
根据我的理解,当你打电话时.懒惰< T>的价值.然后它将调用内部的构造函数.从示例中,它立即被调用,所以为什么要添加Lazy< T>?
解决方法:
假设您将其修改为不使用Lazy< T>.
public class AsyncCache<TKey, TValue>
{
private readonly Func<TKey, Task<TValue>> _valueFactory;
private readonly ConcurrentDictionary<TKey, Task<TValue>> _map;
public AsyncCache(Func<TKey, Task<TValue>> valueFactory)
{
if (valueFactory == null) throw new ArgumentNullException("loader");
_valueFactory = valueFactory;
_map = new ConcurrentDictionary<TKey, Task<TValue>>();
}
public Task<TValue> this[TKey key]
{
get
{
if (key == null) throw new ArgumentNullException("key");
return _map.GetOrAdd(key, toAdd => _valueFactory(toAdd));
}
}
}
See the remarks in the documentation:
If you call
GetOrAdd
simultaneously on different threads,addValueFactory
may be called multiple times, but its key/value pair might not be added to the dictionary for every call.
因此,如果同时对同一个键进行多次访问,则可能会多次为同一个键调用_valueFactory.
现在如何使用Lazy< T>.解决问题?尽管多个Lazy< Task< TValue>>实例可能由并发调用创建,只有一个将从GetOrAdd返回.因此,只有一个人可以访问其Value属性.因此,每个键只会发生一次对_valueFactory的调用.
这当然是一个理想的特征.如果我创建了一个AsyncCache< string,byte []>使用lambda url =>创建的缓存DownloadFile(url),我不希望一堆并发请求缓存[myUrl]多次下载文件.
标签:c,asynchronous,lazy-initialization 来源: https://codeday.me/bug/20190609/1207094.html