Is there a way to pass variable from SetUp to TearDown?

I have a stack with users.

    public class UserProvider
    {
        
        private static ConcurrentStack<IUser> usersConcurrentStack = new ConcurrentStack<IUser>(new List<IUser> { new User1(), new User2() });
        public static Semaphore semaphore = new Semaphore(2, 2);
        
        public static IUser GetUser()
        {
            semaphore.WaitOne();
            popped = usersConcurrentStack.TryPop(out IUser user);
            return user;
        }

        public static void ReturnUser(IUser user)
        {
            usersConcurrentStack.Push(user);
            semaphore.Release();
        }  
    }

I want my tests to pick up one free user and put it back after test.

        IUser user; // This part is wrong. This value is modified by other threads.
        
        [SetUp]
        public void Preconditions()
        {
            user = UserProvider.GetUser(); // Take user from stack
            loginPage.Login(user);
        }

        [Parallelizable]
        [Test]
        public void CatalogSearch()
        {
            //Some testing
        }

        ... a lot of parallel tests here

        [Parallelizable]
        [Test]
        public void AnotherTest()
        {
            //Some testing
        }

        [TearDown]
        public void TakeScreenshotIfTestFailed()
        {
            UserProvider.ReturnUser(user); //Put user back in stack
        }

The problem is that variable "IUser user" is modified by other threads and in teardown method I put back wrong value. How can I pass the same value which was in setup to teardown?

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum