从 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 是微软的官方回答)。

您也可以通过非常简单的测试自己检查(ctrue):

var q1 = stateManager.GetOrAddAsync<IReliableDictionary<string, string>>("MyDict")
                     .GetAwaiter().GetResult();
var q2 = stateManager.GetOrAddAsync<IReliableDictionary<string, string>>("MyDict")
                     .GetAwaiter().GetResult();
var c = q1 == q2;