비어있는 try문 후에 있는 finally 문

안녕하세요! 요즘 멀티쓰레드 공부한다고 .Net 코드를 보고 있는데
이런 코드가 있어서 어떤 의민지 몰라 여쭤봅니다!!

비어있는 try문을 사용하고 finllay에서 중요한 작업을 합니다!

보고있는 함수 전체를 올리겠습니다!

        /// <summary>
        /// Local helper function to Take or Peek an item from the bag
        /// </summary>
        /// <param name="result">To receive the item retrieved from the bag</param>
        /// <param name="take">True means Take operation, false means Peek operation</param>
        /// <returns>True if succeeded, false otherwise</returns>
        private bool TryTakeOrPeek(out T result, bool take)
        { 
            // Get the local list for that thread, return null if the thread doesn't exit 
            //(this thread never add before) 
            ThreadLocalList list = GetThreadList(false);
            if (list == null || list.Count == 0)
            {
                return Steal(out result, take);
            }
 
            bool lockTaken = false;
            try
            {
                if (take) // Take operation
                {
#pragma warning disable 0420
                    Interlocked.Exchange(ref list.m_currentOp, (int)ListOperation.Take);
#pragma warning restore 0420
                    //Synchronization cases:
                    // if the list count is less than or equal two to avoid conflict with any stealing thread
                    // if m_needSync is set, this means there is a thread that needs to freeze the bag
                    if (list.Count <= 2 || m_needSync)
                    {
                        // reset it back to zero to avoid deadlock with stealing thread
                        list.m_currentOp = (int)ListOperation.None;
                        Monitor.Enter(list, ref lockTaken);
 
                        // Double check the count and steal if it became empty
                        if (list.Count == 0)
                        {
                            // Release the lock before stealing
                            if (lockTaken)
                            {
                                try { } //<--- 여기입니다!! 여기!! 👋
                                finally
                                {
                                    lockTaken = false; // reset lockTaken to avoid calling Monitor.Exit again in the finally block
                                    Monitor.Exit(list);
                                }
                            }
                            return Steal(out result, true);
                        }
                    }
                    list.Remove(out result);
                }
                else
                {
                    if (!list.Peek(out result))
                    {
                        return Steal(out result, false);
                    }
                }
            }
            finally
            {
                list.m_currentOp = (int)ListOperation.None;
                if (lockTaken)
                {
                    Monitor.Exit(list);
                }
            }
            return true;
        }

마이크로소프트 사람들이… 어떤 이유에서 저런 코드를 만들어 놓았을까요?

혹시… 저런 패턴으로 사용하시는 분들 계시면 이 패턴에 대한 의견 받아볼 수 있을까요?!

감사합니다!

좋아요 3

finally 문은 어떠한 예외가 발생하더라도 실행됩니다. Monitor.Enter를 통해 list에 대한 lock을 취득한 상태에서 스레드가 중단되어 deadlock이 발생하는 것을 막기 위한 목적으로 생각합니다.

좋아요 6

@루나시아 님이 말씀하신 것 처럼 스레드가 중간에 중단되도 반드시 처리가 완료되도록 보장하기 위한 방법입니다.
다음 페이지를 읽어 보시면 될거 같습니다.

좋아요 8

연휴 끝나고 전달해 주신 링크의 글을 읽어보았습니다.
finally 블록에 있는 코드는 실행 중에 쓰레드가 종료 되어도
끝까지 모두 실행 된 후에 종료 되게 되어있군요!!!

좋은 글 전달해 주셔서 감사합니다! :+1:

좋아요 5