当前位置:  开发笔记 > 编程语言 > 正文

如何使用Lazy处理并发请求?

如何解决《如何使用Lazy处理并发请求?》经验,为你挑选了1个好方法。

我是C#的新手,并试图了解如何使用Lazy.

我需要通过等待已经运行的操作的结果来处理并发请求.对数据的请求可以与相同/不同的凭证同时进行.

对于每个唯一的凭证集,最多可以有一个GetDataInternal调用正在进行中,其中一个调用的结果在准备就绪时返回给所有排队的服务员

private readonly ConcurrentDictionary> Cache
= new ConcurrentDictionary>();

public Data GetData(Credential credential)
{
    // This instance will be thrown away if a cached
    // value with our "credential" key already exists.
    Lazy newLazy = new Lazy(
        () => GetDataInternal(credential),
        LazyThreadSafetyMode.ExecutionAndPublication
    );

    Lazy lazy = Cache.GetOrAdd(credential, newLazy);
    bool added = ReferenceEquals(newLazy, lazy); // If true, we won the race.
    Data data;

    try
    {
       // Wait for the GetDataInternal call to complete.
       data = lazy.Value;
    }
    finally
    {
        // Only the thread which created the cache value
        // is allowed to remove it, to prevent races.
        if (added) {
            Cache.TryRemove(credential, out lazy);
        }
    }

    return data;
}

这是正确的使用方式Lazy还是我的代码不安全?


更新:

开始使用MemoryCache而不是ConcurrentDictionary?如果是,那么如何创建一个键值,因为它是一个string内部MemoryCache.Default.AddOrGetExisting()



1> usr..:

这是对的.这是一个标准模式(删除除外),它是一个非常好的缓存,因为它可以防止缓存加盖.

我不确定你想在计算完成后从缓存中删除,因为计算将一遍又一遍地重做.如果您不需要删除,则可以通过基本删除后半部分来简化代码.

注意,Lazy在异常情况下存在问题:存储异常并且永远不会重新执行工厂.问题永远存在(直到人重新启动应用程序).在我看来,这Lazy在大多数情况下完全不适合生产使用.

这意味着诸如网络问题之类的瞬态错误可能会导致应用永久不可用.

推荐阅读
勤奋的瞌睡猪_715
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有