C# 这本ConcurrentDictionary&x2B;懒惰<;任务<;T>&燃气轮机;代码工作?
有人说,.NET/.NET内核的C# 这本ConcurrentDictionary&x2B;懒惰<;任务<;T>&燃气轮机;代码工作?,c#,.net,asynchronous,concurrentdictionary,C#,.net,Asynchronous,Concurrentdictionary,有人说,.NET/.NET内核的ConcurrentDictionaryGetOrAdd方法在使用Func委托计算要插入到字典中的值时(如果键不存在)不是线程安全的 我相信,当使用concurrentdirectionary的GetOrAdd方法的工厂方法时,如果在“同一时间”发生多个请求,则可以“同时/快速连续”多次调用它。这可能是浪费,尤其是如果通话“昂贵”。(@panagiotis kanavos比我解释得更好)。有了这个假设,我很难理解我编写的一些示例代码是如何工作的 我已经试过了,但我
ConcurrentDictionary
GetOrAdd
方法在使用Func
委托计算要插入到字典中的值时(如果键不存在)不是线程安全的
我相信,当使用concurrentdirectionary
的GetOrAdd
方法的工厂方法时,如果在“同一时间”发生多个请求,则可以“同时/快速连续”多次调用它。这可能是浪费,尤其是如果通话“昂贵”。(@panagiotis kanavos比我解释得更好)。有了这个假设,我很难理解我编写的一些示例代码是如何工作的
我已经试过了,但我一直在努力理解它是如何工作的
我读过的一个常见建议/想法是在ConcurrentDictionary
中有一个Lazy
值。其思想是,Lazy
阻止其他调用执行底层方法
规范中负责起重作业的主要部分如下:
public static async Task<DateTime> GetDateFromCache()
{
var result = await _cache.GetOrAdd("someDateTime", new Lazy<Task<DateTime>>(async () =>
{
// NOTE: i've made this method take 2 seconds to run, each time it's called.
var someData = await GetDataFromSomeExternalDependency();
return DateTime.UtcNow;
})).Value;
return result;
}
公共静态异步任务GetDateFromCache()
{
var result=await\u cache.GetOrAdd(“someDateTime”,new Lazy(async()=>
{
//注意:我已经让这个方法每次调用都需要2秒的时间来运行。
var someData=await GetDataFromSomeExternalDependency();
return DateTime.UtcNow;
})).价值;
返回结果;
}
我是这样读的:
- 检查字典中是否存在
键someDateTime
- 如果是,请将其退回。
因为我假设(上面)键/值中的值是一个
惰性的
是的,确实如此 等待者每次都会打电话。如果每次调用一个wait(因为Lazy保护其他调用者不同时调用所有调用者),那么我认为每次独立调用的结果将是不同的DateTime
wait不是一个调用,它更像是“当结果可用时继续执行”。访问
将创建任务,这将启动对Lazy.Value
的调用,该调用最终返回日期时间。你可以等待任务,不管你想等待多少次,都可以得到相同的结果。GetDataFromSomeExternalDependency
ConcurrentDictionary GetOrAdd方法不是线程安全的,因为这些答案根本不是这样说的。他们说的是,工厂方法虽然是线程安全的,但如果同时调用多次,就不能保证只产生一个结果。如果发生这种情况,将只使用wait每次调用的
值中的一个。任务是已激活的承诺,而不是函数指针。调用
不会运行承诺,而是等待它产生结果。多次调用await
将不会再次运行任务,它将返回await
的第一个结果,对于Lazy求值,实际上并不需要它-当您调用Lazy
时,您现在就想要答案GetDateFromCache
没有异步工厂方法,因此使用了ConcurrentDictionary
将异步工厂方法转换为同步对象。本质上,它同步可能的并发工厂调用Lazy
Lazy确保只成功调用一次(默认情况下,确保在给定时间点只进行一次尝试)。第一次运行成功,因此后续每次调用都不会发生。请求完成任务的(因为延迟保护其他调用方不同时进行所有调用)。。。每次独立调用。
没有任何作用。它只是再次提供相同的值。如果它没有完成(在飞机上),它只是阻塞,直到它准备好。这与我的观点是一致的。结果