C#闭包和自制的SpinLock.RecursiveEnter

C#闭包和自制的SpinLock.RecursiveEnter,c#,multithreading,locking,closures,spinlock,C#,Multithreading,Locking,Closures,Spinlock,实际上,我只是想了解C#中的多线程 所以我有一个名为{TKey,TValue}的类,它有一个私有字典{TKey,CachedValue{TValue},作为缓存。CachedValue是一个包装器,它对TValue有强引用和弱引用。在预定义的时间之后,将创建一个任务以使StrongReference无效并将其放入WeakReference。我还实现了一个HashSet,它跟踪要逐出的keyValuePairs。(添加到发生弱化时,从调用SetValue时删除)GC完成其工作后立即创建另一个任务以

实际上,我只是想了解C#中的多线程

所以我有一个名为{TKey,TValue}的类,它有一个私有字典{TKey,CachedValue{TValue},作为缓存。CachedValue是一个包装器,它对TValue有强引用和弱引用。在预定义的时间之后,将创建一个任务以使StrongReference无效并将其放入WeakReference。我还实现了一个HashSet,它跟踪要逐出的keyValuePairs。(添加到发生弱化时,从调用SetValue时删除)GC完成其工作后立即创建另一个任务以逐出所有提到的对

实际上我不需要递归锁,但我遇到了一些问题,当一些存储的信息被递归地询问时,因为一个构造序列需要这样做

因此,我提出了以下代码:(更新,以前是一种无法使用的扩展方法)

所以我现在要做的是:

    private void Evict()
    {
        RecursiveEnter(() =>
            {
                foreach (TKey key in toEvict)
                {
                    _dict.Remove(key);
                }
            }
        );
    }
好吧,如果我使用 我的问题是:风险是什么?当线程以这种方式使用闭包时,是否会导致问题


感谢您的投入;-)

马上,方法调用100%不起作用:SpinLock是一种值类型,必须通过引用(
RecursiveEnter(ref-SpinLock-SpinLock,Action)
)而不是通过值传递

例如,见


我不确定这是否是您使用的最佳方式:您应该从更高级别的原语(可能是ReaderWriterLockSlim)开始,并通过仔细的测试和理解来完善内容。

ha,好的,很好,谢谢;-)你知道,有些人喜欢修补;-)但是如果我把它称为字段_spinLock,比如上面的(马上更新)会怎么样?要查看ReaderWriterLockSlim,顺便说一句;-)修补是很棒的,但是多线程和锁是百万分之一bug的丰富来源,因此您必须非常小心,可能应该多读一点。使用
SpinLock
,您必须竭尽全力才能实现自己的目标,这是一个原因:它并不是真正为您的场景而设计的。另外两个问题是,除非专门创建,否则SpinLock不一定跟踪
IsHeldByCurrentThread
在调用Enter之后,您必须检查值
gotLock
,因为您可能实际上没有成功地获取它(),所以您不应该不检查就调用
action()
。我认为传入操作本身没有什么错,但是您应该通过try/finally来保护锁。但请注意,我对MSDN示例的测试表明,常规锁比自旋锁快。
    private void Evict()
    {
        RecursiveEnter(() =>
            {
                foreach (TKey key in toEvict)
                {
                    _dict.Remove(key);
                }
            }
        );
    }