【问题标题】:Azure table storage query returning data from wrong partition?Azure 表存储查询从错误的分区返回数据?
【发布时间】:2012-04-29 00:10:06
【问题描述】:

我正在使用 azure 表存储,并且正在尝试快速迭代表。

我一定是做错了,但我这辈子都不知道为什么;

当我只指定一个分区时,我最终会得到 MULTIPLE 分区的结果。 IE。如果我只使用“pkey1”来约束查询,我会为“pkey1”返回 1000 个结果,然后为“pkey2”返回 325 个结果

完全不知道这是怎么发生的……

这是我正在使用的代码:

private CloudTableClient _client;
private string _tableName;
private class QueryState
{
    public CloudTableQuery<T> Ctq;
    public Action<IEnumerable<T>> Populator;
    public ManualResetEvent Mre;
    public string Pkey;

    public QueryState(CloudTableQuery<T> ctq, Action<IEnumerable<T>> populator, ManualResetEvent mre, string pkey)
    {
        Populator = populator;
        Ctq = ctq;
        Mre = mre;
        Pkey = pkey;
    }
}

    public void ParallelQueryWithClause(Action<IEnumerable<T>> populator, string[] partitionKeys)
    {
        List<ManualResetEvent> mre = new List<ManualResetEvent>();
        foreach (string pKey in partitionKeys)
        {
            //_retry.Go(tsc =>
            //    {
                    TableServiceContext tsc =  _client.GetDataServiceContext();
                    ManualResetEvent m = new ManualResetEvent(false);
                    mre.Add(m);
                    CloudTableQuery<T> query = tsc.CreateQuery<T>(_tableName).Where(e => e.PartitionKey == pKey).AsTableServiceQuery<T>();
                    Action<IAsyncResult> act  = null;
                    act = result =>
                        {
                            int retries = 0;
                            while (retries++ < 5)
                            {
                                try
                                {
                                    QueryState qsInternal = result.AsyncState as QueryState;
                                    CloudTableQuery<T> ctq = qsInternal.Ctq;
                                    ResultSegment<T> seg = ctq.EndExecuteSegmented(result);
                                    if (seg.Results.Count() > 0)
                                        populator(seg.Results);
                                    if (seg.ContinuationToken != null)
                                    {
                                        ctq.BeginExecuteSegmented(seg.ContinuationToken, iasync => act(iasync), qsInternal);
                                    }
                                    else
                                    {
                                        m.Set();
                                    }
                                    break;
                                }
                                catch(Exception ex)
                                {
                                    Logger.LogError(ex);
                                }
                            }
                        };
                    query.BeginExecuteSegmented(iasync => act(iasync), new QueryState(query, populator, m, pKey));
                //});
        }
        ManualResetEvent.WaitAll(mre.ToArray());
    }

以及示例调用代码:

AzureTableStorage<ProductEntity> _ats = new AzureTableStorage<ProductEntity>("Products");
string[] partitions = new string[] { "pkey1" };

    Dictionary<string, int> cntr = new Dictionary<string, int>();
    _ats.ParallelQueryWithClause(p =>
    {
        lock (cntr)
        {
            foreach (ProductEntity pe in p)
            {
                if (cntr.ContainsKey(pe.PartitionKey))
                    cntr[pe.PartitionKey]++;
                else
                    cntr.Add(pe.PartitionKey, 1);
            }
        }
    }, partitions);

希望这是有道理的,有人可以提供帮助!

【问题讨论】:

    标签: c# .net asynchronous azure cloud


    【解决方案1】:

    您可能会遇到正在修改闭包值的情况。 http://marlongrech.wordpress.com/2010/06/02/closures-in-c-can-be-evil/ 这将使用 null 的 pKey 运行查询,实际上不会按 pKey 过滤并因此返回表中的所有值。

    尝试替换

    foreach (string pKey in partitionKeys)
    

    foreach (string pKeyTmp in partitionKeys)
    {
       string pKey = pKeyTmp;
    

    【讨论】:

    • 啊哈-是的。我真傻!非常感谢您的回复 - 我正想着这个!
    猜你喜欢
    • 2016-08-05
    • 1970-01-01
    • 2015-08-03
    • 2019-10-07
    • 1970-01-01
    • 2014-07-27
    • 1970-01-01
    • 2017-09-30
    • 2019-04-09
    相关资源
    最近更新 更多