2

当事件触发时,它们使用线程池中的线程。因此,如果您有一堆事件的触发速度比它们返回的速度快,那么您就会耗尽线程池。因此,只要您有一个事件处理程序方法,它没有任何其他控制来限制线程进入的速率,并且不能保证快速返回,并且您不会在其中煞费苦心地实现 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
            }
        }
    }
4

1 回答 1

1

到目前为止,这是我找到的最佳答案。是否存在任何等效于非阻塞 lock() 的速记来缩短它?

static object _myLock;
void myMethod ()
{
    if ( Monitor.TryEnter(_myLock) )
    {
        try
        {
            // Do stuff
        }
        finally
        {
            Monitor.Exit(_myLock);
        }
    }
    else
    {
        // then I failed to get the lock.  Optionally do stuff.
    }
}
于 2013-02-18T14:59:34.953 回答