2012-04-29 125 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