GraphEngine中的死锁
问题描述:
使用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。
答
@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.");
谢谢,L.H.!我必须道歉,因为我的问题过于简单。我的CellID来自迭代不同的CellType,LoadCell在第54次呼叫时被阻塞,而不是第一次。这就是我怀疑违规的原因。但是,我也用ToList()来规避它。但是,如果它们存在,这将使Trinity内的任何聪明的迭代器实现都无用。 –
@AndreasHassmann我看到你想要什么,我找到了另一个解决方案:如果我们不想更新迭代器中的任何数据,我们可以将Trinity存储设置为“只读”模式,这将启用任意操作而不用担心锁。我的解决方案是首先初始化存储并将存储保存到磁盘,然后在加载和迭代存储之前放置这些代码: 'TrinityConfig.CurrentRunningMode = RunningMode.Embedded; TrinityConfig.ReadOnly = true; Global.LocalStorage.LoadStorage();' –
再次感谢,L.H.这听起来好像它不能在运行时切换,对吧?我将不得不重新连接到数据库。你是梁何?我想和一个建立它的人讨论一下Trinity,而不会在这里的公共空间乱扔垃圾...... –