ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 此MSDN上的Lazy目的示例

2019-06-09 20:56:14  阅读:211  来源: 互联网

标签:c asynchronous lazy-initialization


我一直在读这个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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有