天青TableQuery線程安全的我有我已經連續查詢一些基本Azure的表:與Parallel.ForEach
var query = new TableQuery<DynamicTableEntity>()
.Where(TableQuery.GenerateFilterCondition("PartitionKey",
QueryComparisons.Equal, myPartitionKey));
foreach (DynamicTableEntity entity in myTable.ExecuteQuery(query)) {
// Process entity here.
}
加快這,我這個並行像這樣:
Parallel.ForEach(myTable.ExecuteQuery(query), (entity, loopState) => {
// Process entity here in a thread-safe manner.
// Edited to add: Details of the loop body below:
// This is the essence of the fixed loop body:
lock (myLock) {
DataRow myRow = myDataTable.NewRow();
// [Add entity data to myRow.]
myDataTable.Rows.Add(myRow);
}
// Old code (apparently not thread-safe, though NewRow() is supposed to create
// a DataRow based on the table's schema without changing the table state):
/*
DataRow myRow = myDataTable.NewRow();
lock (myLock) {
// [Add entity data to myRow.]
myDataTable.Rows.Add(myRow);
}
*/
});
這會產生顯着的加速,但結果往往會略有不同(即,某些實體偶爾會有所不同,儘管返回的實體數量完全相同)。
從這個和一些網絡搜索,我得出結論,上面的枚舉並不總是線程安全的。該文檔似乎表明,只有在表格對象是公共靜態的情況下才能保證線程安全,但這對我沒有任何影響。
有人可以建議如何解決這個問題嗎?是否有平行Azure表查詢的標準模式?
枚舉器不必是線程安全的,「Parallel.ForEach()」可以處理該問題。如果實體共享某個狀態,則可能會出現問題。 – svick 2014-10-05 13:37:03
你能澄清一下稍微不同的結果嗎?如果您在Parallel.ForEach中記錄所有實體,您是否按不同的順序獲得同一組實體? – 2014-10-05 16:47:42
我已經對實體進行了排序以確定確切的差異,並且這些集合幾乎完全相同。然而,偶爾會有一個特定實體丟失,而另一個實體被重複(與我連續得到的結果相比,這些結果總是相同的,並且可能包含表格內容的基本事實)。這似乎是一般模式 - 一些實體丟失了,但其他實體卻被複制以保持實體數量相同。就好像某些索引沒有以線程安全的方式遞增,從內存中讀取實體時導致爭用條件。 – 2014-10-06 00:22:06