代码之家  ›  专栏  ›  技术社区  ›  soren.enemaerke

从StateManager正确初始化ReliableCollection

  •  0
  • soren.enemaerke  · 技术社区  · 7 年前

    对于以下两种伪模式中哪一种是在有状态的服务结构服务中实例化/使用可靠集合的正确方法,有人有任何见解吗?具体地说,想知道一种方法是否更具性能、更耗内存或者更容易出错。

    方法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(将集合存储为类上的成员变量)

    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执行惰性初始化检查,然后使用类成员。

    我们看到的大多数示例都使用方法1,但是方法2背后的思想是将可靠的字典存储在实例字段中,并避免 StateManager.GetOrAddAsync 同时集中处理 StateKey 这对于使用许多方法的大型服务和可能更可靠的集合可能是有益的。

    希望了解这两种方法中是否存在任何缺陷或效率低下(显然,方法2更详细,使用的代码行更多,但这不是主要问题)。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Oleg Karasik    7 年前

    实际上,没有真正的理由缓存 StateManager.GetOrAddAsync 除了保存的内存分配 Task 物体或使其在有 StateManager 可用不合适。

    原因很简单,因为 状态管理员 已缓存的实例 IRealiableState 为你。所以它每次返回相同的实例 状态管理器.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;
    
    推荐文章