我有一些使用ReaderWriterLockSlim的代码。我在构造某个对象时获取了一个写锁定,并在该对象稍后处理时释放它。但是,由于这些来电的来源,我不能保证他们会在同一个线程上,这是ReaderWriterLockSlim的要求。
我认为合理的解决方案是在专用线程上运行对象的构造和处理,并让调用代码等待该任务完成(但保持线程处于活动状态)。这看起来很混乱,但如果没有大规模重组我们的代码,我就无法想到另一种方法。
是否存在允许我在同一个线程上运行两个任务的现有TaskScheduler子类?
我当然愿意采用另一种做法。
答案 0 :(得分:0)
我遇到了类似的问题,所以我希望我的解决方案能够帮到你。
基本上,问题是ReaderWriterLockSlim具有线程亲和性,这意味着获得锁定的线程是唯一可以释放它的线程。
解决这个问题的方法是创建一个专用线程,但与你建议的相反,这个线程将专门用于获取和释放锁。
我猜您的代码看起来像这样:
public class ClassUsingReaderWriterLockSlim
{
private ReaderWriterLockSlim rwsLock;
public void MethodThatAcquiresLock()
{
rwsLock.EnterWriteLock();
}
public void MethodThatReleasesLock()
{
rwsLock.ExitWriteLock();
}
}
解决问题的代码如下所示:
public class ClassUsingReaderWriterLockSlim
{
private ReaderWriterLockSlim rwsLock;
Thread dedicatedThreadForReaderWriterLockSlim;
Queue<string> commandsForDedicatedThread;
public ClassUsingReaderWriterLockSlim()
{
commandsForDedicatedThread = new Queue<string>();
dedicatedThreadForReaderWriterLockSlim = new Thread(ThreadFunction);
dedicatedThreadForReaderWriterLockSlim.Start();
}
private void ThreadFunction(object obj)
{
while (!terminatingCondition)
{
// Wait until something is in queue...
if (commandsForDedicatedThread.Count > 0)
{
switch (commandsForDedicatedThread.Dequeue())
{
case "ENTER LOCK":
rwsLock.EnterWriteLock();
case "EXIT LOCK":
rwsLock.EnterWriteLock();
default:
// Do nothing...
}
}
}
}
public void MethodThatAcquiresLock()
{
commandsForDedicatedThread.Enqueue("ENTER LOCK");
}
public void MethodThatReleasesLock()
{
commandsForDedicatedThread.Enqueue("EXIT LOCK");
}
}
那么,对于你的生产代码,你会有点不同,但基本的想法是有专门的线程,将进行锁定和解锁,这样,从哪个线程调用到来是不重要的应该锁定和解锁代码/资源的方法......
希望这会对你有所帮助。