2017-03-05 93 views
3

使用GraphEngine有一段時間我經常在對GraphEngine執行一些操作時發現自己有死鎖線程。嵌套調用絕對不在菜單上。但現在我遇到一些奇怪的事情:GraphEngine中的死鎖

foreach(long cellID ...) 
{ 
    byte[] buffer; 

    // the next line will block on the 54th call... 
    Global.LocalStorage.LoadCell(cellID, out buffer); 
} 

疑不存在的CellID我的調用包裝與

if(Global.LocalStorage.Contains(cellID)) 
{ ... } 

但是現在這個調用塊indefinitly。

這是一個錯誤?或

呼叫阻塞在哪些情況下會發生?

Cheerio, Andreas。

回答

3

@Andreas Hassmann,我遇到了類似的問題,所以我想你的麻煩可能是由foreach循環中的...造成的。

我使用了一個迭代器,如Global.LocalStorage.xxxCell_Accessor_Selector().Select(c => c.CellID.Value)。在這種情況下,當Global.LocalStorage.LoadCell()獲取鎖時,存儲的鎖沒有被釋放,導致死鎖。

如果您的問題與我的問題完全相同,則解決方案將爲.ToList()應用於迭代器。

這裏是我的代碼來重現您的問題。

的TSL:

cell struct MyCell 
{ 
    int A; 
} 

的代碼:

for (int i = 0; i < 100; i++) 
{ 
    MyCell mc = new MyCell(i); 
    Global.LocalStorage.SaveMyCell(i, mc); 
} 

var ids = Global.LocalStorage.MyCell_Accessor_Selector().Select(c => c.CellID.Value); 

Console.WriteLine("1 start."); 
foreach (long cellID in ids.ToList()) 
{ 
    byte[] buffer; 
    Global.LocalStorage.LoadCell(cellID, out buffer); 
    Console.WriteLine(cellID); 
} 
Console.WriteLine("1 done."); 

Console.WriteLine("2 start."); 
foreach (long cellID in ids) 
{ 
    byte[] buffer; 
    Global.LocalStorage.LoadCell(cellID, out buffer); 
    Console.WriteLine(cellID); 
} 
Console.WriteLine("2 done."); 
+0

謝謝,L.H.!我必須道歉,因爲我的問題過於簡單。我的CellID來自迭代不同的CellType,LoadCell在第54次呼叫時被阻塞,而不是第一次。這就是我懷疑違規的原因。但是,我也用ToList()來規避它。但是,如果它們存在,這將使Trinity內的任何聰明的迭代器實現都無用。 –

+0

@AndreasHassmann我看到你想要什麼,我找到了另一個解決方案:如果我們不想更新迭代器中的任何數據,我們可以將Trinity存儲設置爲「只讀」模式,這將啓用任意操作而不用擔心鎖。我的解決方案是首先初始化存儲並將存儲保存到磁盤,然後在加載和迭代存儲之前放置這些代碼: 'TrinityConfig.CurrentRunningMode = RunningMode.Embedded; TrinityConfig.ReadOnly = true; Global.LocalStorage.LoadStorage();' –

+0

再次感謝,L.H.這聽起來好像它不能在運行時切換,對吧?我將不得不重新連接到數據庫。你是梁何?我想和一個建立它的人討論一下Trinity,而不會在這裏的公共空間亂扔垃圾...... –