如何解决多线程函数中的 LockRecursionException
我不知道如何描述它,但我得到了一个例外,即在编写好的代码时不应有任何位置。这个异常是关于 readerwriterlockslim 的问题,它是 LockRecursionException;它出现在“ScreenLocker.EnterReadLock();”线。找不到我的代码和描述的问题,或者互联网上可能有什么问题,这就是我在这里写这个问题并向大家寻求帮助的原因。这是我有问题的代码:
public static List<Dictionary<int,int>> RunTasks(ScreenScanning ss)
{
var listofTasks = new List<Task>();
List<Dictionary<int,int>> PosXOfBlocksAndMeaningOfIt = new List<Dictionary<int,int>>();
for (var i = 0; i <= BlocksOnYAxisOnScreen; i++)
{
ScreenLocker.EnterReadLock();
var t = new Task(() =>
{
PosXOfBlocksAndMeaningOfIt.Add(ss.XAxysScan(PosYOfRowsToScan[i],Screen,ref ScreenLocker));
});
listofTasks.Add(t);
}
Task.WaitAll(listofTasks.ToArray());
return PosXOfBlocksAndMeaningOfIt;
}
public Dictionary<int,int> XAxysScan(int posY,Bitmap screen,ref readerwriterlockslim screenLocker)
{
screenLocker.ExitReadLock();
Dictionary<int,int> partOfMainTable = new Dictionary<int,int>();
partOfMainTable.Add(666,posY); //used in BotViewUpdate in DataToTableInterpreter
for (int i = 0; i <= 1920; i++)
{
if (screen.GetPixel(i,posY) == ColorsInRow[0])
{
if (IsFarmable(posY,ColorsInRow,i,screen))
{
partOfMainTable.Add(i,1);
}
}
else if (IsBackground(BackgroundColors,posY,screen))
{
partOfMainTable.Add(i,0);
}
else
{
partOfMainTable.Add(i,2);
}
}
return partOfMainTable;
}
你怎么能看到我在进入 XAxysScan 功能后立即释放锁。
解决方法
你怎么能看到我在进入 XAxysScan 功能后立即释放锁。
ReaderWriterLockSlim
是一个 synchronization object,它允许多个线程读取一个资源,但只允许 1 个资源写入它(理想情况下)。
之所以重要,是因为ReaderWriterLockSlim
实现这种效果的具体方式,需要一个叫做Managed Thread Affinity的东西,这基本上意味着无论Task
或Thread调用EnterReadLock()
必须是相同 Task
或调用 ExitReadLock();
的线程。
当我们看下面的时候,我们可以看到你有 RunTasks(ScreenScanning ss)
进入了锁,但是你立即开始了一个新的孩子 Task
并将 ReaderWriterLockSlim
作为对 {{ 的引用传递1}}。
XAxysScan()
只有进入锁的同一个 ScreenLocker.EnterReadLock();
var t = new Task(() =>
{
PosXOfBlocksAndMeaningOfIt.Add(ss.XAxysScan(PosYOfRowsToScan[i],Screen,ref ScreenLocker));
});
才能释放该锁。至少对于像 Task
这样使用 Managed Thread Affinity 的同步对象。
考虑将 ReaderWriterLockSlim
移到 EnterReadLock()
方法中。
XAxysScan()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。