搜索IReliableDictionary的最佳方法是什么?

RWi*_*son 4 azure-service-fabric

根据这些帖子:

将IReliableDictionary转换为IList

什么是查询可靠字典集合的最佳方法

我应该能够使用Linq来查询IReliableDictionary,但看起来这个接口不再实现IEnumerable而且Linq扩展不可用.至少在Microsoft.ServiceFabric.Data.Interfaces程序集的5.0.0.0版中.

如果这是真的,那么搜索IReliableDictionary的最佳方法是什么?

Vac*_*cek 10

是的,我们确实从GA版本中的Reliable Collections中删除了IEnumerable.正如Allan T所提到的,Reliable Collections与常规.NET集合并不完全相同,即使它们代表相同的基础数据结构.您可能注意到的一个重大差异是所有操作都是异步的,因为锁定语义和I/O用于复制和磁盘读取.后者推动了删除IEnumerable的决定,因为它是严格同步的,我们不是.相反,我们现在使用IAsyncEnumerable,但它不支持完整的LINQ扩展方法集.

我们正在研究异步LINQ扩展方法,但与此同时,有两种方法可以使用IAsyncEnumerable.

Eli Arbel在Gist上有异步扩展方法,它们为System.Interactive.Async以及Select,SelectMany和Where的异步实现提供了桥梁.

或者你可以将IAsyncEnumerable包装在一个简单的IEnumerable中,它只是用同步方法包装异步调用,这将再次为你提供完整的LINQ扩展方法.然后,您可以在常规LINQ查询中使用扩展方法:

        using (ITransaction tx = this.StateManager.CreateTransaction())
        {
            var x = from item in (await clusterDictionary.CreateEnumerableAsync(tx)).ToEnumerable()
                   where item.Value.Status == ClusterStatus.Ready
                   orderby item.Value.CreatedOn descending
                   select new ClusterView(
                       item.Key,
                       item.Value.AppCount,
                       item.Value.ServiceCount,
                       item.Value.Users.Count(),
                       this.config.MaximumUsersPerCluster,
                       this.config.MaximumClusterUptime - (DateTimeOffset.UtcNow - item.Value.CreatedOn.ToUniversalTime()));

        }
Run Code Online (Sandbox Code Playgroud)


Nic*_*ett 7

我不知道这是否是“最佳”方式,但我一直在使用以下方法

public static async Task<IList<KeyValuePair<Guid, T>>> QueryReliableDictionary<T>(IReliableStateManager stateManager, string collectionName, Func<T, bool> filter)
{
    var result = new List<KeyValuePair<Guid, T>>();

    IReliableDictionary<Guid, T> reliableDictionary =
        await stateManager.GetOrAddAsync<IReliableDictionary<Guid, T>>(collectionName);

    using (ITransaction tx = stateManager.CreateTransaction())
    {
        IAsyncEnumerable<KeyValuePair<Guid, T>> asyncEnumerable = await reliableDictionary.CreateEnumerableAsync(tx);
        using (IAsyncEnumerator<KeyValuePair<Guid, T>> asyncEnumerator = asyncEnumerable.GetAsyncEnumerator())
        {
            while (await asyncEnumerator.MoveNextAsync(CancellationToken.None))
            {
                if (filter(asyncEnumerator.Current.Value))
                    result.Add(asyncEnumerator.Current);
            }
        }
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

您可以通过传入 StateManager、您希望查询的集合的名称以及带有查询逻辑的 lambda 函数来使用该方法。例如:

var queryResult = await QueryReliableDictionary<string>(this.StateManager, "CustomerCollection", name => !string.IsNullOrWhiteSpace(name) && (name.IndexOf("fred", StringComparison.OrdinalIgnoreCase) >= 0));
Run Code Online (Sandbox Code Playgroud)