从 StateManager 正确初始化 ReliableCollection
Correct initialization of ReliableCollection from StateManager
是否有人对以下两种伪模式中的哪一种是有状态服务结构服务中 instantiating/utilizing 可靠集合的正确方式有任何见解?具体来说,想知道一种方法是性能更高、内存消耗更多还是更容易出错。
方法 1(从方法内部的 StateManager 获取实例):
public class MyService : IService {
public async Task<string> GetSomeValueAsync(string input){
var reliableDic = await StateManager.GetOrAddAsync<IReliableDictionary<string, string>>(StateKey);
var result = await reliableDic.TryGetValue(input);
return result.HasValue ? result.Value : null;
}
}
方法 2(将集合作为成员变量存储在 class 上)
public class MyService : IService {
private bool _isInitialized;
private readonly object _lock = new object();
private IReliableDictionary<string, string> _dictionary;
private async Task Initialize(){
if (_isInitialized){
return;
}
lock(_lock){
if (_isInitialized){
return;
}
_dictionary = await StateManager.GetOrAddAsync<IReliableDictionary<string, string>>(StateKey);
_isInitialized = true;
}
}
public async Task<string> GetSomeValueAsync(string input){
await Initialize();
var result = await _dictionary.TryGetValue(input);
return result.HasValue ? result.Value : null;
}
}
因此,方法 1 在每个方法中从 StateManager 中获取字典,而方法 2 进行惰性初始化检查,然后使用 class 个成员。
我们看到的大多数样本都使用方法 1,但方法 2 背后的想法是将可靠的字典存储在实例字段中,避免每个方法中的任何 StateManager.GetOrAddAsync
命中,以及集中处理StateKey
这可能对具有许多方法和可能更可靠的集合的大型服务有益。
很想了解这两种方法是否存在任何缺陷或效率低下(显然方法 2 更冗长并且使用更多代码行,但这不是主要问题)。
实际上,没有真正的理由缓存 StateManager.GetOrAddAsync
的结果,除了节省 Task
对象的内存分配或使其在 StateManager
不可用的地方可用。
原因很简单 - StateManager
已经为您缓存了 IRealiableState
的实例。所以它 returns 每次你做 StateManager.GetOrAddAsync
相同的实例(here 是微软的官方回答)。
您也可以通过非常简单的测试自己检查(c
是 true
):
var q1 = stateManager.GetOrAddAsync<IReliableDictionary<string, string>>("MyDict")
.GetAwaiter().GetResult();
var q2 = stateManager.GetOrAddAsync<IReliableDictionary<string, string>>("MyDict")
.GetAwaiter().GetResult();
var c = q1 == q2;
是否有人对以下两种伪模式中的哪一种是有状态服务结构服务中 instantiating/utilizing 可靠集合的正确方式有任何见解?具体来说,想知道一种方法是性能更高、内存消耗更多还是更容易出错。
方法 1(从方法内部的 StateManager 获取实例):
public class MyService : IService {
public async Task<string> GetSomeValueAsync(string input){
var reliableDic = await StateManager.GetOrAddAsync<IReliableDictionary<string, string>>(StateKey);
var result = await reliableDic.TryGetValue(input);
return result.HasValue ? result.Value : null;
}
}
方法 2(将集合作为成员变量存储在 class 上)
public class MyService : IService {
private bool _isInitialized;
private readonly object _lock = new object();
private IReliableDictionary<string, string> _dictionary;
private async Task Initialize(){
if (_isInitialized){
return;
}
lock(_lock){
if (_isInitialized){
return;
}
_dictionary = await StateManager.GetOrAddAsync<IReliableDictionary<string, string>>(StateKey);
_isInitialized = true;
}
}
public async Task<string> GetSomeValueAsync(string input){
await Initialize();
var result = await _dictionary.TryGetValue(input);
return result.HasValue ? result.Value : null;
}
}
因此,方法 1 在每个方法中从 StateManager 中获取字典,而方法 2 进行惰性初始化检查,然后使用 class 个成员。
我们看到的大多数样本都使用方法 1,但方法 2 背后的想法是将可靠的字典存储在实例字段中,避免每个方法中的任何 StateManager.GetOrAddAsync
命中,以及集中处理StateKey
这可能对具有许多方法和可能更可靠的集合的大型服务有益。
很想了解这两种方法是否存在任何缺陷或效率低下(显然方法 2 更冗长并且使用更多代码行,但这不是主要问题)。
实际上,没有真正的理由缓存 StateManager.GetOrAddAsync
的结果,除了节省 Task
对象的内存分配或使其在 StateManager
不可用的地方可用。
原因很简单 - StateManager
已经为您缓存了 IRealiableState
的实例。所以它 returns 每次你做 StateManager.GetOrAddAsync
相同的实例(here 是微软的官方回答)。
您也可以通过非常简单的测试自己检查(c
是 true
):
var q1 = stateManager.GetOrAddAsync<IReliableDictionary<string, string>>("MyDict")
.GetAwaiter().GetResult();
var q2 = stateManager.GetOrAddAsync<IReliableDictionary<string, string>>("MyDict")
.GetAwaiter().GetResult();
var c = q1 == q2;