비어있는 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개의 좋아요