2012-04-29 141 views
2

我正在使用天蓝色表格存储,并且我试图快速迭代表格。Azure表存储查询返回错误分区的数据?

我必须做错了,但我不能为我的生活看到为什么;

当我只指定一个分区时,我最终得到了多个分区的结果。 也就是说如果我只要使用“pkey1”约束查询,我回来了“pkey1” 1000个结果,然后325“pkey2”

,如何这可能发生完全糊涂..

这是代码我使用:

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); 

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

回答

1

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

尝试用

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

啊哈更换

foreach (string pKey in partitionKeys) 

- 是的。 我真傻! 谢谢你的回复 - 我正在用这个去掉我的脑海! – user865864 2012-04-29 12:30:42