如何使用延迟来处理并发请求? [英] How to use Lazy to handle concurrent request?

查看:314
本文介绍了如何使用延迟来处理并发请求?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C#中新,并试图了解如何与工作

I'm new in C# and trying to understand how to work with Lazy.

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

I need to handle concurrent request by waiting the result of an already running operation. Requests for data may come in simultaneously with same/different credentials.

对于每个组唯一的凭据可以有在进步最多一个GetDataInternal电话,结果从一个调用返回的所有排队的服务员,当它准备好

For each unique set of credentials there can be at most one GetDataInternal call in progress, with the result from that one call returned to all queued waiters when it is ready

private readonly ConcurrentDictionary<Credential, Lazy<Data>> Cache
= new ConcurrentDictionary<Credential, Lazy<Data>>();

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

    Lazy<Data> 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;
}

是正确的方式使用或我的代码是不是安全

Is that right way to use Lazy or my code is not safe?

更新:

这是好主意,开始使用的MemoryCache 而不是 ConcurrentDictionary ?如果是,如何创建一个键值,因为它是一个字符串 MemoryCache.Default.AddOrGetExisting()

Is it good idea to start using MemoryCache instead of ConcurrentDictionary? If yes, how to create a key value, because it's a string inside MemoryCache.Default.AddOrGetExisting()

推荐答案

这是正确的。这是一个标准的模式(除了删除),这是一个非常好的高速缓存,因为它可以防止缓存乱窜。

This is correct. This is a standard pattern (except for the removal) and it's a really good cache because it prevents cache stampeding.

我不知道你想从缓存中删除当计算做是因为计算将重做一遍又一遍的方式。如果您不需要去除您可以通过删除基本下半场简化代码。

I'm not sure you want to remove from the cache when the computation is done because the computation will be redone over and over that way. If you don't need the removal you can simplify the code by basically deleting the second half.

请注意,该具有一个异常的情况下的问题:异常被存储和工厂将永远不会被重新执行。这个问题永远持续(直至人类重新启动应用程序)。在我心目中这使得完全不适合在大多数情况下生产。

Note, that Lazy has a problem in the case of an exception: The exception is stored and the factory will never be re-executed. The problem persists forever (until a human restarts the app). In my mind this makes Lazy completely unsuitable for production use in most cases.

这意味着一个短暂的错误,例如作为一个网络的问题可以使应用程序永久不可用。

This means that a transient error such as a network issue can render the app unavailable permanently.

这篇关于如何使用延迟来处理并发请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆