2

イベントがトリガーされると、スレッドプールのスレッドが使用されます。したがって、戻るよりも速くトリガーするイベントがたくさんある場合は、スレッドプールを使い果たします。したがって、スレッドが入る速度を制限する他のコントロールがなく、すぐに戻る保証がないイベントハンドラーメソッドがあり、その中に100%スレッドセーフなコードを丹念に実装していない場合はいつでもメソッドでは、スレッド制御を実装するのがおそらく最善です。明らかに簡単なことは、イベント処理メソッド内でlock()を実行することですが、これを行うと、最初のスレッドの後のすべてのスレッドがキューでブロックされ、ロック領域に入るのを待って、スレッドプールからすべてのスレッドを占有します。このメソッド内に別のスレッドがあることを検出し、代わりにすぐに中止する方がおそらく良いでしょう。

問題は、すでに実行されている別のスレッドを検出し、後続のスレッドをすばやく中止する方法があるということです。ただし、「const」を使用し、低レベルでロックフラグを手動で処理するため、C#っぽくはありません。もっと良い方法はありますか?

これは基本的にlock()機能の直接複製ですが、ブロッキングMonitor.Enter()を使用する代わりに、非ブロッキングInterlocked.Exchangeを使用します。

    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 に答える