递归锁定(即在同一线程上工作的锁)
Recursion locking (i.e. a lock that works on the same thread)
我想要一个锁来防止从相同的线程输入一段代码,以使其更能防止无限递归。也就是说,类似于:
private static object RecurseLock = new object();
public void PartiallyRecursiveMethod()
{
if (TryEnter(RecurseLock))
{
try
{
Console.WriteLine("Hello ");
// we want to do it again now
PartiallyRecursiveMethod();
}
finally
{
Release(RecurseLock);
}
}
Console.WriteLine("world!");
}
这样调用 PartiallyRecursiveMethod
的输出就是“Hello world!”。 (或者里面可能有一个换行符,我忘记了 Console.WriteLine
是如何工作的)
TryEnter 应该只适用于 current 线程。不应阻塞其他线程。
C# 中是否已经有一些东西可以做到这一点,或者我必须自己编写吗?我相信所有常见的嫌疑人(Monitor.TryEnter
、SemaphoreSlim
等)只会获得一个排除 不同 线程的锁;在这里使用它们只会导致堆栈溢出。
这需要在 .NET 2 中。
顺便说一下,我知道这个要求表明代码非常糟糕,重写代码真的会更明智。尽管如此,如果 .NET 提供类似的东西,我还是很感兴趣。
正如一些人指出的那样,在 .Net 2.x 中,您可以使用 [ThreadStatic]
来做到这一点:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
class Program
{
static void Main()
{
Parallel.Invoke(test, test, test);
}
static void test()
{
if (_thisThreadAlreadyHere)
{
Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} is already working.");
return;
}
_thisThreadAlreadyHere = true;
try
{
Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} is working.");
Thread.Sleep(1000);
test();
Thread.Sleep(1000);
Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} has completed.");
}
finally
{
_thisThreadAlreadyHere = false;
}
}
[ThreadStatic]
static bool _thisThreadAlreadyHere;
}
}
但是,我想说尝试以这种方式解决 "infinite recursion" 问题有些可疑。我本以为应该有更好的方法来修复逻辑 - 这似乎是一种贴膏药的方法。
我想要一个锁来防止从相同的线程输入一段代码,以使其更能防止无限递归。也就是说,类似于:
private static object RecurseLock = new object();
public void PartiallyRecursiveMethod()
{
if (TryEnter(RecurseLock))
{
try
{
Console.WriteLine("Hello ");
// we want to do it again now
PartiallyRecursiveMethod();
}
finally
{
Release(RecurseLock);
}
}
Console.WriteLine("world!");
}
这样调用 PartiallyRecursiveMethod
的输出就是“Hello world!”。 (或者里面可能有一个换行符,我忘记了 Console.WriteLine
是如何工作的)
TryEnter 应该只适用于 current 线程。不应阻塞其他线程。
C# 中是否已经有一些东西可以做到这一点,或者我必须自己编写吗?我相信所有常见的嫌疑人(Monitor.TryEnter
、SemaphoreSlim
等)只会获得一个排除 不同 线程的锁;在这里使用它们只会导致堆栈溢出。
这需要在 .NET 2 中。
顺便说一下,我知道这个要求表明代码非常糟糕,重写代码真的会更明智。尽管如此,如果 .NET 提供类似的东西,我还是很感兴趣。
正如一些人指出的那样,在 .Net 2.x 中,您可以使用 [ThreadStatic]
来做到这一点:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
class Program
{
static void Main()
{
Parallel.Invoke(test, test, test);
}
static void test()
{
if (_thisThreadAlreadyHere)
{
Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} is already working.");
return;
}
_thisThreadAlreadyHere = true;
try
{
Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} is working.");
Thread.Sleep(1000);
test();
Thread.Sleep(1000);
Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} has completed.");
}
finally
{
_thisThreadAlreadyHere = false;
}
}
[ThreadStatic]
static bool _thisThreadAlreadyHere;
}
}
但是,我想说尝试以这种方式解决 "infinite recursion" 问题有些可疑。我本以为应该有更好的方法来修复逻辑 - 这似乎是一种贴膏药的方法。