当事件触发时,它们使用线程池中的线程。因此,如果您有一堆事件的触发速度比它们返回的速度快,那么您就会耗尽线程池。因此,只要您有一个事件处理程序方法,它没有任何其他控制来限制线程进入的速率,并且不能保证快速返回,并且您不会在其中煞费苦心地实现 100% 线程安全代码方法,最好实现一些线程控制。显而易见的简单事情是在事件处理方法中使用 lock() ,但如果这样做,第一个线程之后的所有线程将阻塞在队列中,等待进入锁定区域,从线程池中占用所有线程。最好检测另一个线程在这个方法中,然后快速中止。
问题是:我有一种方法可以检测到另一个已经在运行的线程,并快速中止后续线程。但由于使用“const”并在低级别手动处理锁定标志,它似乎不是很 C#-ish。有没有更好的办法?
这基本上是 lock() 功能的直接复制,但使用非阻塞 Interlocked.Exchange,而不是使用阻塞 Monitor.Enter()
public class FooGoo
{
private const int LOCKED = 0; // could use any arbitrary value; I choose 0
private const int UNLOCKED = LOCKED + 1; // any arbitrary value, != LOCKED
private static int _myLock = UNLOCKED;
void myEventHandler()
{
int previousValue = Interlocked.Exchange(ref _myLock, LOCKED);
if ( previousValue == UNLOCKED )
{
try
{
// some handling code, which may or may not return quickly
// maybe not threadsafe
}
finally
{
_myLock = UNLOCKED;
}
}
else
{
// another thread is executing right now. So I will abort.
//
// optional and environment-specific, maybe you want to
// queue some event information or set a flag or something,
// so you remember later that this thread aborted
}
}
}